2 puntos por GN⁺ 2023-11-14 | 1 comentarios | Compartir por WhatsApp
  • Los componentes web pueden parecer la versión para navegador de los componentes de React, pero en realidad se acercan más a un modelo que toma el HTML existente como base y le agrega funcionalidad
  • La diferencia clave está en el renderizado antes de ejecutar JavaScript: en lugar de pasar datos a un elemento personalizado vacío, resulta más natural envolver HTML con significado dentro de un elemento personalizado
  • Un HTML web component extiende el marcado existente, mientras que un elemento vacío cuyo contenido y funcionalidad dependen por completo de JavaScript se parece más a un JavaScript web component
  • Si la componentización al estilo React está acostumbrada al reemplazo, los componentes web exigen una forma de pensar en aumentación (augmentation): agregar funcionalidad sin perder el contenido
  • En la plataforma web, como ocurrió con HTML5, fetch y la evolución relacionada con TypeScript, las buenas ideas tienden a sobrevivir durante mucho tiempo como refuerzos en vez de desplazar por completo la tecnología existente

Los componentes web y los componentes de React tienen una naturaleza distinta

  • El nombre “Web components” puede sonar como el equivalente en la plataforma web a los componentes de React
    • El JSX de React usa la forma <MyComponent>, y los componentes web pueden usar la forma <my-component>
    • Pero si intentas crear componentes web como si estuvieras creando componentes de React, es fácil terminar frustrado
  • Las dos tecnologías priorizan funciones y formas de uso distintas en su diseño
    • Si intentas usar una como si fuera la otra, chocas con la dirección natural de cada tecnología

Los componentes web HTML encajan mejor con la aumentación que con el reemplazo

  • Un componente típico de React puede consistir en pasar datos mediante propiedades a un componente vacío, y dejar que JavaScript renderice todo el contenido
<UserAvatar
  src="https://example.com/path/to/img.jpg";
  alt="..."
/>
  • Un componente web también puede escribirse así si solo miramos la forma exterior
<user-avatar
  src="https://example.com/path/to/img.jpg";
  alt="..."
></user-avatar>
  • Pero la fuerza propia de los componentes web está en que permiten renderizar antes de JavaScript
    • Los componentes de React no pueden funcionar de esa manera
  • Por eso, en lugar de un “shell component” vacío, encaja mejor una estructura donde el contenido principal se construye en HTML y luego se envuelve con un elemento personalizado para añadir funcionalidad
<user-avatar>
  <img src="https://example.com/path/to/img.jpg"; alt="..." />
</user-avatar>
  • La distinción de Jeremy en “HTML web components” se enfoca en si el elemento personalizado extiende el marcado existente
    • Si el elemento personalizado está vacío, no es un HTML web component
    • Si envuelve y amplía el marcado existente, se acerca más a un HTML web component
  • Un “JavaScript web component” es una forma en la que el contenido y la funcionalidad de un elemento vacío dependen por completo de JavaScript
<user-avatar
  src="https://example.com/path/to/img.jpg";
  alt="..."
></user-avatar>
  • En esta forma, sin JavaScript no tiene significado para el usuario final
  • En cambio, un HTML web component conserva significado y contenido incluso sin JavaScript, y cuando JavaScript está disponible, la funcionalidad se añade encima
<user-avatar>
  <img src="https://example.com/path/to/img.jpg"; alt="..." />
</user-avatar>

En la web, el enfoque de aumentación perdura más

  • La razón por la que el enfoque de aumentación encaja tan bien en la web es que su naturaleza favorece el mejoramiento progresivo con resiliencia, y además se adapta bien a cambiar repetidamente algo tan grande como la propia web
  • Muchas buenas ideas de frameworks y librerías del ecosistema web, incluso cuando son absorbidas por la plataforma, suelen incorporarse como refuerzos en lugar de reemplazar por completo la tecnología previa
    • XHTML intentó reemplazar HTML4, pero HTML5 intentó reforzar HTML4, y HTML5 ganó
    • Las librerías de networking intentaron reemplazar XMLHttpRequest, y las buenas ideas terminaron trasladándose al estándar fetch
    • Hoy fetch también existe en varios entornos fuera del navegador
    • Las buenas ideas de Sass y jQuery también llegaron al navegador
    • Las buenas ideas de TypeScript también están entrando al navegador como un refuerzo, no como un reemplazo de la tecnología existente
  • También se puede ver a los componentes web como parte del traslado del modelo de componentes de React al navegador, pero están más cerca de reforzar la forma en que la web ya funciona que de reemplazarla
  • Si buscas un enfoque tecnológico duradero, elegir la aumentación y la mejora en lugar del reemplazo va más en línea con la dirección de la web

1 comentarios

 
GN⁺ 2023-11-14
Comentarios de Hacker News
  • Esperaba que este artículo explicara qué hace realmente user-avatar o qué aporta, pero al final nunca quedó claro.
    Si solo contiene estilos, no veo por qué no usar simplemente una clase de CSS, y parece mucho más natural que user-avatar reciba un atributo src en lugar de obligar a poner una etiqueta img dentro cada vez.
    Más que intentar “reemplazar” HTML, Vue/React/Angular se parecen más a una capa construida encima de HTML/CSS/JS; si renderizaran todo en canvas, ese argumento me parecería más convincente.
    Cuando se anunciaron por primera vez los Web Components me entusiasmaron, pero sus funciones integradas son demasiado limitadas y no da mucho la sensación de que realmente ayuden a crear aplicaciones web como lo hace un framework.
    Las alternativas a los grandes frameworks, sobre todo cosas como htmx, se ven más bien como la línea de jQuery con un poco de azúcar sintáctico encima, así que para construir aplicaciones web se siente como un gran retroceso.

    • Estoy de acuerdo con que “las alternativas a los grandes frameworks parecen azúcar sintáctico sobre jQuery”, pero no queda claro por qué eso sería una elección completamente equivocada para construir aplicaciones web.
      Si por “aplicación web” se refiere a algo como Google Sheets, entonces sí; pero esta corriente anti-React parece estar criticando más bien la costumbre de instalar un framework por defecto y construir todo desde cero, incluso cuando no hace falta.
      En realidad hay muchos sitios web donde lo único necesario es “una capa ligera de interactividad”.
    • Creo que el artículo de Eric Meyer muestra mucho mejor la intención: https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the...
      La ventaja clave es la mejora progresiva: la etiqueta img ya tiene un comportamiento por defecto, así que puedes apoyarte en ese renderizado base y “mejorar” solo lo necesario con componentes web.
    • Como faltan ejemplos concretos, este artículo se siente un poco como una idea surgida en la ducha.
    • Un mejor ejemplo que muestra más concretamente el punto del artículo es este: https://www.zachleat.com/web/details-utils
      El componente details-utils mejora el comportamiento del componente HTML integrado detail.
      Incluso si JavaScript está desactivado por alguna razón, el componente detail sigue funcionando como siempre, y cuando JavaScript está activado o termina de descargarse, obtiene comportamientos mejorados, como cerrarse al hacer clic fuera.
      Lo reutilizable en este enfoque es justamente esa mejora de comportamiento.
      Al ver este componente web del creador de 11ty entendí mejor el punto del artículo, y esa sensación que tuve al ver por primera vez los Web Components —“al final igual necesitan JavaScript y sin eso no funcionan”— aparece en el mismo punto del artículo de Rich Harris: https://dev.to/richharris/why-i-don-t-use-web-components-2ci...
    • No sé si has usado htmx, pero esa crítica parece errada porque htmx aborda un problema distinto al de la experiencia de usuario con JavaScript del lado del cliente que resolvía jQuery.
      htmx es, sobre todo, una manera de extender el paradigma de HTML renderizado en el servidor para hacer actualizaciones parciales de página en lugar de recargar la página completa.
  • Si quieres ver más de la idea de “HTML Web Components”, también vale la pena leer estos artículos.
    https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the... - “So there you have it: a few thousand words on my journey through coming to understand and work with these fully-Light-DOM web components, otherwise known as custom elements. Now all they need is a catchy name, so we can draw more people to the Light Side of the Web.”
    https://adactio.com/journal/20618 propone un nombre bastante bueno.

    • No termino de entender el punto.
      Como es incómodo de escribir, al final terminas necesitando un framework ligero encima de un framework integrado como Lit, y Lit es incluso más grande que Preact.
      Además, no resuelve problemas reales como la gestión de estado o el enrutamiento, así que probablemente haya que traer todavía más cosas.
      Puede que obtengas componentes reutilizables, pero si piensas en traer a un entorno con React un componente web que internamente usa Vue, ya no suena muy lógico.
    • Me alegra mucho ver una corriente que impulsa componentes web sin Shadow DOM.
      La belleza y la elegancia de la web venían de su estructura declarativa, y eso permitía la observabilidad y la capacidad de modificación.
      Shadow DOM siempre me pareció más bien un deseo corporativo de levantar barreras de encapsulamiento más altas y de tener más certezas, y personalmente no compartía ese objetivo.
      Este artículo muestra cómo el trabajo con Light DOM puede componerse.
      Siempre pensé que los componentes web o elementos personalizados deberían poder modificar por sí mismos el DOM interno, mover a sus hijos y crear contenido nuevo.
      Por ejemplo, una página o framework puede insertar íconos, y un elemento de avatar de usuario podría insertar el nombre o elementos decorativos.
      Eso sí, una preocupación con Light DOM/HTML Web Components es que Shadow DOM sí ofrece algunas ventajas de rendimiento.
      Como desarrollador, me resulta fácil imaginar que puede reducir la cantidad de elementos que los selectores CSS tienen que recorrer, y ojalá ese beneficio también pudiera aprovecharse de alguna manera.
      De verdad se agradece este enfoque más ligero para ver los elementos personalizados y los Web Components, y gracias también por los enlaces.
    • Tal vez se podría acortar ese nombre y llamarlos simplemente HTML components.
  • La afirmación de que “se puede renderizar antes de JavaScript. Un componente de React jamás puede hacerlo” es difícil de sostener de forma categórica, y con renderizado del lado del servidor sí puede renderizarse antes del JavaScript del cliente
    Me parece que el ejemplo es demasiado simple para demostrar la postura del autor
    Un componente web que maneje cambios de estado habría sido un mejor punto de comparación, y el argumento también habría sido mejor

    • Es una buena observación y, a la inversa, también podría decirse que los componentes web tampoco pueden porque deben registrarse con JavaScript antes de que cargue la página
      Hay soluciones de hydration, pero por lo general son peores, tienen concesiones sorprendentes y a menudo perjudican la composabilidad
    • El mayor problema de Web Components es que no son amigables con el renderizado del lado del servidor
    • No sé cómo un “HTML Web Component” manejaría los cambios de estado
      Viendo solo el ejemplo que envuelve una etiqueta img, no me quedó clara la ventaja, y aunque se pueden agrupar y reutilizar elementos comunes, para la interacción igual sigue haciendo falta JavaScript
      Incluso el texto alternativo de la imagen del ejemplo hoy en día suele ser dinámico por temas de localización, así que sin JavaScript podría faltar contenido
  • Siento que por fin entendí Web Components: https://github.com/kennyfrc/cami.js
    “No Build Steps, No Client-Side Router, No JSX, No Shadow DOM. We want you to build an MPA, with mainly HTML/CSS, and return HTML responses instead of JSON. Then add interactivity as needed.”
    “Declarative templates with lit-html. Supports event handling, attribute binding, composability, caching, and expressions.”

    • La belleza de Web Components está en que puedes encontrar o crear una clase base que funcione de la manera que necesitas
      En lo personal, me gusta una clase estilo componente de clase de React con una máquina de estados integrada inspirada en XState
      https://github.com/codewithkyle/supercomponent/blob/master/s...
    • Me pregunto si has usado HTMX
      La dirección parece bastante similar, y puede que del lado de HTMX la comunidad incluso sea más grande
      Si lo has usado, me da curiosidad qué fue lo que le faltó
    • Básicamente están cambiando JSX por un DSL personalizado no estándar y llamándolo una victoria
  • “web components” no es una sola cosa, y tampoco se “crea un web component”
    “Web Components” es el nombre de la Web Components API, que agrupa tres cosas
    Lo que realmente se crea son elementos personalizados, y además puedes usar Shadow DOM o plantillas HTML con ellos
    De esas tres, la más importante son los elementos personalizados
    La idea central es “crear más elementos HTML”, así que tú decides por completo qué atributos y qué API de JavaScript van a soportar
    La forma de ponerlos en la página, interactuar con ellos y escuchar eventos es exactamente la misma que con cualquier otro elemento HTML
    Si sabes escribir páginas web “a la antigua”, ya sabes usar elementos personalizados; solo necesitas aprender a declararlos

  • Recientemente empecé a probar Web Components sin entorno de build
    Sin npm, bun o webpack, sin dependencias, y escritos en TypeScript
    IntelliJ los compila automáticamente a JavaScript, y la vista del navegador inyecta un pequeño manejador de detección de cambios para actualizar en tiempo real durante el desarrollo
    Hasta ahora no he tenido problemas
    Lo que parece frenar a Web Components son los HTML Modules
    Sería bueno poder enlazar a un archivo .html en vez de a uno .js para importar un componente web, pero por ahora, si quieres usar plantillas o algo más complejo, tienes que hacer una inyección fea como .innerHtml = \...``
    Pensé que eso sería un problema, pero el IDE analiza bastante bien las cadenas de plantilla

    • HTML Modules fue descartado y eliminado, y fue reemplazado por importaciones solo de JavaScript
      Y esa tampoco es la única razón que está frenando a Web Components
  • No me convence mucho la afirmación de que “React no es una mejora, sino un reemplazo”
    Al final, React también renderiza elementos HTML y les agrega manejadores de eventos de JavaScript
    Envolver un img en un componente de React no le quita la funcionalidad a img, sino que agrega cosas encima; es decir, es una mejora
    Puede que el autor haya trabajado en otras bases de código de React, pero en mi experiencia nosotros usamos las funciones integradas del navegador tal cual, salvo que haya una razón para no hacerlo
    Tal vez solo tuve suerte

    • Que cualquier arquitectura web termine renderizando elementos HTML es obvio, y ese no era el punto
      El punto es que el enfoque de “HTML Web Component”, a diferencia de React, no depende de JavaScript para empezar a renderizar
    • Creo que la diferencia central que plantea el artículo es más o menos esta
      En React, según el modelo de renderizado del navegador, es “carga de la página → carga del componente”, mientras que con Web Components es más bien “carga de la página → renderizado básico → carga del componente”
      Incluso alguien con JavaScript desactivado puede ver algo con web components, mientras que con React puede que no vea nada; y si hay JavaScript, se puede pasar a un estado de renderizado más avanzado
    • En algunos casos React también dificulta más el acceso a funciones integradas
      Por ejemplo, si asignas onchange a un elemento, React te da algo más parecido al evento input que al evento change
      En realidad no es exactamente ninguno de los dos, sino un evento sintético más cercano a input que a change
      Si de verdad quieres change, tienes que usar una referencia al elemento y adjuntar el manejador manualmente dentro de un efecto
    • Depende de la arquitectura de la aplicación
      Si con React devuelves HTML desde el servidor, envolver un img en un componente de React sí cuenta como una mejora del elemento existente
      Pero si todo se renderiza del lado del cliente, ese img al final no puede separarse del componente de React
    • Al leer esa parte pensé en el caso inverso, o sea, meter React dentro de otro HTML
      Por experiencia, React es excelente cuando le dejas toda la estructura de la página de arriba abajo, pero puede volverse difícil si intentas encajarlo dentro de una estructura ya existente mientras haces cosas como renderizado del lado del servidor
  • Si buscas una forma duradera de hacer las cosas, la conclusión de optar por mejora y realce en vez de reemplazo también coincide con mi experiencia
    Gracias a esa filosofía, mis proyectos web han durado mucho tiempo con el mínimo de mantenimiento y dependencias

  • Los web components deberían hacer una sola cosa, mientras que los frameworks de JavaScript se parecen más a un ecosistema completo
    Hice un web component de reproductor de video que podía recibir varias entradas, y la más compleja era un archivo torrent
    Podía portarlo a Vue/React con StencilJS [0], pero funcionaba perfectamente incluso sin eso
    Con solo poner esa etiqueta junto con la clase exportada desde awesomePlayer.js, ya tenías un reproductor de video HTML5 para torrents listo para copiar y pegar
    También recomiendo mucho imitar, cuando sea posible, los elementos HTML existentes
    Por ejemplo, usé src porque video funciona así, y entonces quien lo use puede interactuar sin tener que ir a buscar la documentación
    [0] https://stenciljs.com/

  • Me cuesta estar de acuerdo con que los componentes de frameworks frontend sean puramente de reemplazo y no componibles
    En la superficie puede parecer así, pero en mis componentes uso mucho slots y es fácil de implementar y funciona de forma natural
    En cambio, los Web Components suelen mostrarse metiendo una cantidad enorme de código para construir algo como un editor
    Usar slots en Web Components fue doloroso: había que adjuntar muchos nodos manualmente, manejar plantillas como cadenas, y para hacer algo un poco más complejo incluso había que escuchar el evento slotchange
    Esencialmente terminas usando la API del DOM, y si esa API no hubiera sido terrible, ni siquiera habríamos migrado a frameworks frontend como React
    Tampoco estoy de acuerdo con la afirmación secundaria de que XHTML fracasó por no mejorar HTML
    Creo que fracasó porque la aplicación tenía que ser completamente válida y esa validación se dejaba al cliente/navegador
    Si se hubiera usado XHTML de verdad, la página se habría roto por un solo error pequeño en el marcado, y por eso todo el mundo validaba XHTML para prepararse para el futuro, pero ninguna empresa iba a aceptar el riesgo de que el negocio entero se rompiera porque una etiqueta p no se cerró correctamente