- 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
Comentarios de Hacker News
Esperaba que este artículo explicara qué hace realmente
user-avataro 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-avatarreciba un atributosrcen lugar de obligar a poner una etiquetaimgdentro 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.
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”.
La ventaja clave es la mejora progresiva: la etiqueta
imgya tiene un comportamiento por defecto, así que puedes apoyarte en ese renderizado base y “mejorar” solo lo necesario con componentes web.El componente
details-utilsmejora el comportamiento del componente HTML integradodetail.Incluso si JavaScript está desactivado por alguna razón, el componente
detailsigue 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...
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.
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.
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.
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
Hay soluciones de hydration, pero por lo general son peores, tienen concesiones sorprendentes y a menudo perjudican la composabilidad
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 JavaScriptIncluso 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.”
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...
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ó
“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
.htmlen vez de a uno.jspara 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
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
imgen un componente de React no le quita la funcionalidad aimg, sino que agrega cosas encima; es decir, es una mejoraPuede 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
El punto es que el enfoque de “HTML Web Component”, a diferencia de React, no depende de JavaScript para empezar a renderizar
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
Por ejemplo, si asignas
onchangea un elemento, React te da algo más parecido al eventoinputque al eventochangeEn realidad no es exactamente ninguno de los dos, sino un evento sintético más cercano a
inputque achangeSi de verdad quieres
change, tienes que usar una referencia al elemento y adjuntar el manejador manualmente dentro de un efectoSi con React devuelves HTML desde el servidor, envolver un
imgen un componente de React sí cuenta como una mejora del elemento existentePero si todo se renderiza del lado del cliente, ese
imgal final no puede separarse del componente de ReactPor 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 pegarTambién recomiendo mucho imitar, cuando sea posible, los elementos HTML existentes
Por ejemplo, usé
srcporquevideofunciona 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
slotchangeEsencialmente 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
pno se cerró correctamente