Introducción a los web components

Los Web Components llevan entre nosotros muchos años, pero no ha sido hasta estos últimos donde se ha estabilizado completamente y soportado de manera nativa por los navegadores más importantes.

A raíz de este soporte, la estandarización y de la madurez de las herramientas para el desarrollo de los mismos (StencilJS y LitElement) se ha incrementado el uso de los mismos exponencialmente llegando a estar en el día a día de los desarrolladores Front.

Además de lo mencionado anteriormente han aparecido una serie de herramientas que han facilitado el desarrollo y ofrecido a los desarrolladores un acercamiento más sencillo y fácil a esta nueva tecnología. Las más conocidas actualmente son StencilJS y LitElement, las cuales veremos en detalle en los siguientes artículos.

Pero no solo aparecieron estas herramientas, también surgieron otras pero que han quedado en desuso como Bosonic o menos usadas como pueden ser hybrids o slimjs.

¿Cuál es el origen de los Web Components?

Los web components surgieron como una propuesta por parte de Google a la W3C, prácticamente a la vez que apareció el framework AngularJS. En paralelo la W3C trabajaba en el concepto de los web components que “bebían” mucho del concepto utilizado en AngularJS basado en directivas.

Todo esto nacía con una serie de ideas para poder crear nuevos elementos encapsulados y ajenos a cualquier librería. Estas ideas eran:

  • Mantener las etiquetas semánticas y declarativas
  • Estándar recomendado por la W3C sin riesgo de acoplarse a una tecnología en concreto
  • Alto rendimiento sin necesidad de sacrificar tiempo de ejecución
  • Disponible en todos los sitios sin riesgo a su adopción

¿Qué son los Web Components?

Los web components son bloques de código que encapsulan la estructura interna de elementos HTML, incluyendo CSS y JavaScript, permitiendo usarlo en cualquier web y aplicación sin dependencia de ningún tipo.

Si no vamos a la especificación de los componentes web veremos que son una meta-especificación posible gracias a otras cuatro especificaciones:

Estas cuatro especificaciones se pueden usar por sí solas, pero al usarlas combinadas permiten a los desarrolladores definir sus propias etiquetas (custom elements specification), cuyos estilos están encapsulados y aislados (shadow dom), que se puede usar muchas veces (template) y tiene una forma consistente de estar integrados en las especificaciones (ES module).

Actualmente el soporte por parte de los navegadores es completo como se muestra en la imagen.

Ejemplo de componente con StencilJS

Para ver la simplicidad de la creación de un componente la mejor forma es ver un ejemplo en código. A continuación, podéis ver el código de un componente acordeón -sin código css- y lo simple que resulta su estructura y la creación del mismo.

 

import { Component, Prop, Host, h, Event, EventEmitter } from '@stencil/core';

@Component({
    tag: 'ejempllo-ui-accordion',
    styleUrl: 'ui-accordion.scss',
    shadow: true
})
export class Uiaccordion {

    /* Variable que controlará el estado visual de la sección del detalle del acordeon */
    @Prop() detailOpened: boolean;

    /** CustomEvent para controlar la apertura del acordeon */
    @Event({eventName: 'accordionOpened'}) accordionOpen: EventEmitter;

    toggleOpen(event: Event) {
        event.preventDefault();
        this.detailOpened = !this.detailOpened; 
        if(this.detailOpened) this.accordionOpen.emit();
    }

    render() {
        return (
            <Host class={this.detailOpened && 'detailSectionOpened'}>
                <div class="ui-header" onClick={e => this.toggleOpen(e)}>
                    <div><slot name="title" /></div>
                    <i class={`ui-icon icon-arrow ${this.detailOpened && 'transform'}`}></i>
                </div>
                <div class="ui-container">
                    <slot name="bodyContent" />
                    <slot name="footer" />
                </div>
            </Host>
        );
    }
}

 

El componente consta de lo siguiente:

  • Una propiedad booleana "detailOpened" para controlar si el acordeón está abierto o no (así podemos definir desde fuera si queremos que esté inicialmente abierto o si queremos cerrarlo cuando otro componente haga una acción)
  • Un custom event que se emite al abrir/cerrar el acordeón (para que, en caso de tener varios acordeones, avisar de que este se ha abierto y cerrar los demás si queremos)
  • Un método toggleOpen que se ejecuta en el click sobre el componente y cambia el valor del boolean que controla si está abierto o cerrado

Y el resultado con los estilos aplicados sería el siguiente:

En apenas 50 líneas de código de typescript y css tenemos un componente acordeón que podemos utilizar en cualquier página.

Conclusión

Los web components se han expandido de una manera exponencial estos últimos años y ya se pueden considerar una solución factible – al menos en parte – a utilizar en la mayoría de proyectos.

En mi opinión pueden ser muy interesantes para desarrollar pequeñas funcionalidades concretas, o componentes que se repiten una y otra vez en proyectos diferentes, permitiendo una reducción de costes y tiempo muy grandes en proyectos de gran envergadura.

Si trabajas en el mundo Front varios años y participas en varios proyectos te encuentras normalmente con que “podrías” haber usado ese componente que desarrollaste en Angular 9 pero este proyecto es en React y casi tardas lo mismo en crearlo de cero. Con el uso de web components esta problemática desaparece totalmente y como mucho requerirá una nueva versión ampliando o adaptándolo al nuevo requisito con el ahorro en tiempo y dinero que conlleva.