En el anterior artículo de introducción a los web components hablaba sobre el origen y las herramientas que han ido surgiendo a lo largo de los años para facilitar el desarrollo. En este artículo veremos como usar Stencil.js paso a paso, generando un proyecto desde cero usando el starter-app que proporciona la herramienta y desarrollaremos un sencillo componente contador.
Stencil JS es una herramienta de los creadores de Ionic y si hay algo que esta claro es que se han inspirado en los frameworks más populares como Angular o React para coger lo mejor de ambos. Ellos mismos la definen como «El generador mágico de web components reusables».
Stencil combina los mejores conceptos de los frameworks más populares en una herramienta simple y genera componentes web basado en estándares lo que permite utilizar estos componentes sin depender de ningún framework.
Vamos a ver mas en detalle como funciona el Virtual DOM y como consigue esa mejora de rendimiento.
Si has trabajado con React o has escuchado algo de esta librería te sonará el termino ya que es uno de sus principales conceptos y la razón que le permite tener un gran rendimiento a la hora de actualizar el DOM.
El Virtual DOM es una representación en memoria del DOM real que actúa de intermediario entre el estado de la aplicación y el DOM de la interfaz gráfica que visualiza el usuario.
Cada vez que se produce un cambio o se añade un nuevo elemento se genera un nuevo Virtual DOM con el árbol resultante. Como este DOM es virtual la interfaz gráfica no se actualiza, se compara el DOM real con el DOM virtual con el propósito de calcular la forma más optima de realizar estos cambios y de esta forma reducir el coste en términos de rendimiento a la hora de actualizar el DOM.
Se puede ver de una forma simple en este gráfico:
Ejecutamos el siguiente comando en el terminal y seleccionamos entre las tres opciones, en nuestro caso elegimos “app” ya que queremos generar una web entera.
npm init stencil
? Pick a starter › - Use arrow-keys. Return to submit.
❯ ionic-pwa Everything you need to build fast, production ready PWAs
app Minimal starter for building a Stencil app or website
component Collection of web components that can be used anywhere
Dando como resultado la siguiente estructura:
En nuestro caso solo vamos a prestar atención a la carpeta components que es lo que nos interesa en este artículo.
Además del starter-app los creadores de Stencil nos proporcionan un CLI muy completo que nos ayuda también a generar los componentes de una manera muy sencilla y rápida, para hacerlo solo tenemos que ejecutar el siguiente comando en el terminal.
npm run generate
Nos preguntará el nombre del componente y que archivos queremos generar junto al componente (estilos, test unitario y test end to end).
Una vez creado el proyecto vamos a comprobar que todo funciona correctamente ejecutando estos comandos en orden:
Si todo ha ido bien nos abrirá en el navegador la página y tendremos que ver lo siguiente
En los primeros pasos del artículo hemos creado un proyecto web y también nuestro componente “test-component” donde vamos a hacer todo el desarrollo.
El componente de ejemplo que vamos a crear consta de lo siguiente:
Antes de empezara desarrollar el componente vamos a modificar el código para que cuando pulsemos el botón de “Profile page” cargue el nuestro. Para ello tenemos que irnos al archivo “app-root.tsx” y añadir nuestro componente, quedando como se muestra en la código inferior.
<main>
<stencil-router>
<stencil-route-switch scrollTopOffset={0}>
<stencil-route url='/' component='app-home' exact={true} />
<stencil-route url='/profile/:name' component='app-profile' />
<stencil-route url='/test' component='test-component' />
</stencil-route-switch>
</stencil-router>
</main>
Aprovechamos también que hemos añadido nuestro componente y modificamos el nombre del botón “Profile page” por el que queramos en el archivo “app-home.tsx”. El siguiente paso es indicar en el router que vamos a pasar una variable por URL al componente, quedando el código así:
<main>
<stencil-router>
<stencil-route-switch scrollTopOffset={0}>
<stencil-route url='/' component='app-home' exact={true} />
<stencil-route url='/profile/:name' component='app-profile' />
<stencil-route url='/test/:title' component='test-component' />
</stencil-route-switch>
</stencil-router>
</main>
Una vez añadido el componente al router y modificado el nombre del botón ya podemos pasar al código del componente, donde debemos procesar ese valor pasado por la URL y agregar la variable interna del contador con la lógica interna.
Para no alargar demasiado el artículo muestro el resultado del código terminado y vamos viendo paso a paso lo que hemos necesitado añadir.
import { Component, h, Prop, State } from '@stencil/core';
@Component({
tag: 'test-component',
styleUrl: 'test-component.css',
shadow: true
})
export class TestComponent {
@Prop() match: any;
@State() counter;
componentWillLoad() {
this.counter = 0;
}
render() {
return (
<div class="container">
<div class="center">
<h1>¡Hola {this.match.params.title}</h1>
<p>{this.counter}</p>
<div class="buttons">
<button class="button-left" onClick={() => this.increase()}>Sumar</button>
<button class="button-right" onClick={() => this.reset()}>Reiniciar</button>
</div>
</div>
</div>
);
}
increase() {this.counter += 1; }
reset() { this.counter = 0; }
}
Como podemos ver en el código hemos agregado lo siguiente:
Si nos fijamos en la parte HTML podemos ver que hemos añadido el siguiente código para mostrar el valor recibido por parámetro y para mostrar el valor del contador.
<h1>¡Hola {this.match.params.title}</h1>
<p>{this.counter}</p>
Con esto tenemos terminado nuestro pequeño componente contador que aplicando un poco de código CSS quedaría así:
Como hemos podido comprobar crear un componente en Stencil es realmente sencillo y rápido, y más si tenemos en cuenta que usando el CLI proporcionado nos facilita la creación en simples pasos.
Aunque el componente que hemos creado es sencillo, es suficiente para tener una aproximación a las posibilidades que nos brindan los web components, teniendo siempre en mente siempre la compatibilidad con todos los navegadores -incluso con los antiguos usando polyfills- y no depender de ninguna librería.
Espero que este pequeño artículo os haya picado la curiosidad de investigar e indagar más en esta gran herramienta y que en