‘Web components’: presente y futuro en el desarrollo web

6 min lectura
‘Web components’: presente y futuro en el desarrollo web
‘Web components’: presente y futuro en el desarrollo web

BBVA API Market

BBVA Open4u Webcomponents

Los web components son un estándar del W3C que nos permiten desglosar el desarrollo de aplicaciones web en pequeños contenedores que encapsulan marcado, código JavasScript y estilos CSS, recibiendo el nombre de componentes.

Esto nos permite reutilizarlos en diferentes partes de nuestras aplicaciones y también para exponer nuestros servicios en otras aplicaciones con simplemente un tag HTML.

Origen de los web components

Los web components surgieron como propuesta por parte de Google a la W3C, prácticamente a la par que el framework MVC de JavaScript AngularJS, también creado por la compañía del buscador. En este framework se presentaba el concepto de “directiva”, en el que podíamos crear etiquetas HTML propias para encapsular un marcado HTML con su propio ámbito de ejecución.

AngularJS nos proporciona controladores, enrutado, filtros, servicios, etc, y las directivas estaban ahí, aunque en un principio no eran tan utilizadas. Con el tiempo empezaron a extenderse debido a terceros desarrolladores que compartían, a modo de proyectos Open Source, sus implementaciones. De esta manera, en nuestras aplicaciones podíamos importar estos proyectos y utilizarlos en nuestros desarrollos.

Paralelamente, la W3C trabajaba en el concepto de los web components que bebían mucho de este concepto iniciado en AngularJS.

Elementos de un web component

Para crear un web component necesitamos de varios elementos:

– Templates

– Custom Elements

– Shadow DOM

– HTMLImports

1. Templates

Los Templates son un elemento de HTML5 que nos permiten crear plantillas para presentar los datos, y son nativos del navegador. En nuestro HTML tendríamos algo como lo siguiente:

<template id=”profileTemplate”>

  <div class=”profile”>

    <img src=”” class=”profile__img”>

    <div class=”profile__name”></div>

    <div class=”profile__social”></div>

  </div>

</template>

Esto representaría el marcado para un perfil de usuario en una aplicación web. Nada del código englobado dentro de <template> será visible en el navegador hasta que sea activado, aunque esté dentro del código.

Para poder activarlo e inyectarle datos, debemos hacerlo a través de JavaScript con un código similar al siguiente:

var template = document.querySelector(‘#profileTemplate’);

template.querySelector(‘.profile__img’).src = avatar.jpg’;

template.querySelector(‘.profile__name’).textContent = Mi Nombre’;

template.querySelector(‘.profile__social’).textContent = ‘Sígueme en Twitter’;

document.body.appendChild(template);

2. Custom Elements

Los Custom Elements o elementos personalizados nos permiten definir nuestro propio elemento HTML (similar a las directivas de AngularJS).

Según el estándar, la forma correcta de crear un Custom Element es con la función Object.create de JavaScript y el elemento HTMLElement.protoype. Basándonos en el elemento anterior, el código sería como el siguiente:

<template id=”profileTemplate”>

  <div class=”profile”>

    <img src=”” class=”profile__img”>

    <div class=”profile__name”></div>

    <div class=”profile__social”></div>

  </div>

</template>

<script>

var MyElementProto = Object.create(HTMLElement.prototype);

window.MyElement = document.registerElement(‘user-profile’, {

  prototype: MyElementProto

  // other props

});

</script>

De esta manera ya podríamos utilizar el elemento <user-profile> en nuestra aplicación.

3. Shadow DOM

El Shadow DOM es el DOM que encapsula nuestro componente. No pertenece al DOM original del documento o página web, si no que se encuentra dentro del componente que hemos creado. Tiene su propio ámbito de ejecución y su propio estilo CSS. Piensa en ello como un DOM anidado al DOM primario de la página.

Una manera de ver el shadow DOM es en el inspector web del navegador Chrome, clicando en nuestro elemento recién creado, y así podremos ver el DOM que encapsula el componente:

▾<user-profile>

  ▾#shadow-root (user-agent)

  <div class=”profile”>

    <img src=”” class=”profile__img”>

    <div class=”profile__name”></div>

    <div class=”profile__social”></div>

  </div>

 </user-profile>

Esto es así porque en el código fuente únicamente veríamos <user-profile></user-profile>

4. HTML Imports

Al igual que en CSS podemos importar archivos externos con @import y en JavaScript usando ‘require’ (utilizando Node.js o Browserify) o ‘import’ {module} from ‘libreria.js’, con HTML Imports podemos importar ficheros HTML que contengan los web components.

Suponiendo que nuestro <user-profile> lo tenemos en un fichero llamado ‘user-profile.html’ la forma de importarlo en nuestra aplicación sería la siguiente:

<link rel=”import” href=”user-profile.html”>

Compatibilidad en los diferentes navegadores

Como todo estándar web, cada navegador se toma su tiempo en implementarlo y que esté 100% utilizable. Uno de los mejores sitios para comprobar si cierto elemento, propiedad CSS o API JavaScript, está disponible en los navegadores es la web caniuse.com

Pero en concreto para el tema de web components, tenemos una adaptada a los elementos principales del estándar, y es: http://jonrimmer.github.io/are-we-componentized-yet/

BBVA Open4u - webcomponentes caniuse

En ella vemos que en el momento de escribir este artículo Chrome y Opera ya soportan todos los requisitos para implementar y utilizar web components. Firefox prácticamente ya lo soporta a falta de dejar estable los HTML Imports. Safari aún no lo soporta de forma nativa y Microsoft en su versión Edge v13 únicamente soporta los <templates> por el momento.

Pero a través de Polyfills podemos utilizar el estándar en prácticamente cualquier navegador y combinándolos con la librería Polymer (también desarrollada por Google) nos permite crear web components de una forma sencilla, compartirlos y utilizarlos en los navegadores.

Utilizando un WebComponent de Polymer

Lo primero que debemos hacer es importar la librería webcomponents.js, que es un Polyfill desarrollado por el mismo equipo de Polymer para que los web components sean compatibles en navegadores que aún no lo soportan nativamente.

Seguidamente se importa el componente que queramos emplear, por ejemplo el componente de Google Maps.

Y por último, dentro del BODY, ya podemos usar ese componente. El código sería algo similar a esto:

<!DOCTYPE html>

<html lang=”en”>

<head>

  <meta charset=”UTF-8″>

  <title>Ejemplo Polymer</title>

  <script src=”components/webcomponentsjs/webcomponents-lite.min.js”></script>

  <link rel=”import” href=”components/google-map/google-map.html”>

</head>

<body>

  <google-map latitude=”40.415848″ longitude=”-3.701905″ zoom=”15″></google-map>

</body>

</html>

Lo que nos mostraría en el navegador, un mapa como el siguiente:

BBVA Open4u - webcomponents, google maps

Creando un web component con Polymer

Para crear un componente web con Polymer, debemos seguir la guía de estilo y buenas prácticas que promueven desde el equipo de Google. Lo primero que necesitamos es crear un archivo HTML con el nombre del componente que queremos desarrollar.

Dentro de ese archivo importamos Polymer para poder utilizar la etiqueta <dom-module> . El id de dom-module y el ‘is’ de la función Polymer deben tener el mismo nombre que el nombre del webcomponent.

Dentro de <dom-module> insertamos la etiqueta <template> para el marcado HTML, el <script> para el código JavaScript y <style> para el CSS del componente.

<!– Fichero components/contact-card/contact-card.html –>

<link rel=”import” href=”../polymer/polymer.html”>

<dom-module id=”contact-card”>

    <style>

        …

    </style>

    <template>

        <img src=”{{image}}”>

        <span>{{name}}</span>

    </template>

    <script>

        Polymer({

            is: ‘contact-card’,

            properties: {

                name: String,

                image: String

            }

        });

    </script>

</dom-module>

Y lo podemos reutilizar en nuestros desarrollos de la siguiente manera:

<link rel=”import” href=”components/contact-card/contact-card.html”>

<contact-card name=”Carlos Azaustre” image=”avatar.jpg”></contact-card>

La Web orientada a Componentes

En el pasado año vimos como el desarrollo de aplicaciones web se estaba “componetizando”. Con el impulso de React y Polymer, esta nueva forma de desarrollar se está popularizando.

Ahora se piensa en pequeños componentes con su lógica propia y que poco a poco van formando la estructura de una aplicación, en lugar de un código completo Modelo-Vista-Controlador.

Esta nueva metodología de desarrollo la ha popularizado React, la librería creada por Facebook. React, al contrario que Polymer, no crea por defecto componentes web exportables, si no que componetiza la propia aplicación. Esta es la principal diferencia cuando hablamos de components y web components.

Un component es un pedazo en nuestra aplicación, como puede ser un menú, un header, un navbar, un item,etc. Descomponemos la lógica de nuestra aplicación en estos pequeños contenedores sin que sean exportables para otra aplicación.

En cambio un web component se entiende que exporta un API o un servicio de terceros, como puede ser <google-map> o <youtube-video>, o una pasarela de pago como puede ser PayPal o Stripe por medio de unas etiquetas HTML.

Angular por su parte está tendiendo a esta forma de programar. Su nueva versión 2.0 sigue esta metodología de creación de componentes, y en sus versiones 1.x (en concreto la 1.4, la 1.5 que está en fase beta y la futura 1.6) tienden hacia eso.

Desde el equipo de Ingeniería de PayPal se está desarrollando/orientando a directivas, para encapsular dentro de ellas el templating y los controladores. Después en el routing, en lugar de indicar un templateUrl con un HTML y un controlador, se indica la directiva que se quiera cargar para una determinada URL.

Esto casa con que la función directive de Angular será sustituida por el método component en Angular 1.5, cumpliendo el mismo propósito pero ya indicándonos que una directiva no tiene porque ser un contenido HTML muy extenso, puede limitarse a un componente más reducido.

También cuadra con el nuevo sistema de rutas de Angular 2, que ya se puede utilizar en Angular 1.x con ngNewRouter, el cual está orientado a componentes.

Conclusión

Todo parece indicar que el desarrollo web frontend, presente y futuro será basado en componentes. De esta forma dividimos nuestros problemas en trozos más pequeños, con su propio estilo y funcionalidad y los vamos componiendo hasta formar aplicaciones más grandes.

Es la misma lógica que se lleva a cabo en el backend, donde se está pasando de sistemas monolíticos que controlaban toda la lógica de la aplicación, a microservicios con pequeñas tareas asignadas.

Sin duda, estamos en un momento de cambio constante en la web, donde tenemos que estar informados y actualizados para poder sacar ventaja en nuestros desarrollos profesionales.

 

Referencias:

●      WebComponents and Concepts por Todd Motto

●      Aprende a crear WebComponents con Polymer por Abdón Rodríguez

●      La web orientada a componentes por Javier Vélez

●      HTML5Rocks

●      WebComponents.org

Imagen: Steven Depolo

Por Carlos Azaustre:

Carlos Azaustre es ingeniero en Telemática especializado en desarrollo web fullstack con JavaScript. Trabaja con AngularJS y NodeJS. Actualmente es CTO y CoFundador de Chefly, una startup de economía colaborativa que te ayuda a comer comida casera de calidad.

Síguenos en @BBVAAPIMarket

También podría interesarte