Creamos un primer componente, custom element del estándar Web Components, basado en LitElement. Hola Mundo con LitElement.
Comenzar con LitElement es muy sencillo, ya que es únicamente una clase base, sobre la que vamos a extender para crear un Web Component, consiguiendo con ello una serie de ventajas con respecto al estándar Javascript, que ya describimos en el artículo de presentación de LitElement. Sin embargo, debido a la tecnología y el panorama de navegadores, hay una serie de cosas que debes saber, y hacer, para poder comenzar sin quebraderos de cabeza.
En este artículo verás cómo hacer un primer ejemplo de componente basado en LitElement, cómo usarlo en una página web y cómo ejecutar un proyecto mediante un servidor de desarrollo que nos permita ver el componente en marcha en el navegador. Iremos paso a paso y desde cero. Apreciarás que el código en sí para crear un componente es muy sencillo, pero sin embargo, el flujo para su desarrollo se hace un poco más complejo por distintos factores. No obstante, si tienes experiencia en el desarrollo con Javascript no debería resultar mucho problema, porque cualquier framework o librería moderna tiene más o menos los mismos requisitos para funcionar.
Crear el componente
Vamos primero con lo sencillo, que es crear el componente con LitElement. Como ya se explicó, LitElement no es más que una clase base sobre la que tenemos que extender, por herencia, para obtener una serie de beneficios sobre el estándar de los Web Components. Por ello, el primer paso será instalar la dependencia.
Comencemos creando un directorio para nuestra práctica. Te metes con la consola dentro de esa carpeta y lanzas el comando:
npm init
Con eso has iniciado el proyecto frontend. Ahora podemos instalar lit-element con este otro comando:
npm i lit-element
Con eso se ha creado la carpeta "node_modules" y dentro ya tienes LitElement instalado. Ahora podemos usarlo en nuestro componente.
Puedes crear a continuación un archivo Javascript, donde vamos a guardar el código de nuestro componente. Lo normal sería colocar estos archivos dentro de una carpeta llamada "src". Así que crea esa carpeta y dentro colocaremos el archivo del componente que vamos a llamar "my-element.js". Podrías crear la carpeta y el archivo con tu editor de código preferido. Luego tendrás un listado de directorio como este:
Dentro de my-element.js colocaremos el código del elemento que vamos a crear. Nuestro componente tendrá el siguiente código, que ahora te describimos:
import { LitElement, html } from 'lit-element';
export class MyElement extends LitElement {
render() {
return html`
<p>Soy My Element</p>
`;
}
}
customElements.define('my-element', MyElement);
- En la primera línea (import) importamos la definición de "LitElement" y "html". Debes saber que LitElement es la base clase y "html" es una función que nos va a servir para crear el template (la parte visual del componente) mediante una característica más o menos novedosa de Javascript llamada "Tagged Template String Literal". Puedes obtener más información sobre esto en el artículo de LitHTML.
- En el bloque de en medio estamos creando la clase que implementa un componente. Es una clase de ES6 que debes apreciar está extendiendo LitElement (extends LitElement).
- Como contenido de la clase tenemos tan solo un método llamado "render". Este método simplemente devuelve el template que se debe mostrar cuando se usa el componente. Puedes fijarte que en este método usamos el Tagged Template String Literal "html", para generar ese template. El poder del Tagged Template String Literal es interpolar el contenido de datos y además ser reactivo a esos datos, actualizándose automáticamente cuando los datos cambian. De momento hemos colocado una simple cadena que muestra un párrafo con un contenido fijo. Veremos más adelante cómo colocamos esas propiedades.
- En la última línea tenemos el método customElements.define(), que sirve para definir un nuevo componente, de modo que lo entienda el navegador. Este método define() pertenece al estándar de los Web Components y por tanto es Javascript nativo. Recibe dos parámetros, el primero es el nombre del componente a definir y el segundo es el nombre de la clase creada para implementar el componente.
Usar el componente
Con esto hemos conseguido crear nuestro primer componente. Ahora lo podríamos usar tal cual en cualquier proyecto frontend. Para usarlo simplemente lo importamos y colocamos el nombre del componente allá donde se necesite, como si fuera cualquier etiqueta del HTML:
<my-element></my-element>
En nuestra práctica paso a paso vamos a crear un archivo "index.html" en la raíz del proyecto, donde vamos a cargar el código del componente. Ahora el listado de nuestro proyecto será como este:
En el archivo index.html para usar el componente tenemos que cargarlo mediante la correspondiente etiqueta SCRIPT y luego usarlo con la etiqueta del componente. El código de nuestro HTML simplificado al máximo sería el siguiente:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ejemplo con LitElement</title>
<script type="module" src="src/my-element.js"></script>
</head>
<body>
<my-element></my-element>
</body>
</html>
- Fíjate en la etiqueta SCRIPT. Estamos cargando el componente por su nombre de archivo, con la ruta "src/my-element.js".
- Luego, en el bódy, estamos usando el componente "my-element", con su etiqueta correspondiente.
Es así de simple! Aunque para que funcione debemos de tener en cuenta otra serie de cosas que explicaremos a continuación.
Servidor de desarrollo
Para poder ver en marcha correctamente nuestro ejemplo necesitamos contar con un servidor de desarrollo. Esto es porque el Javascript que hemos escrito requiere:
- Primero que usemos http:// en lugar de file://. Así que tenemos que abrirlo desde un servidor local.
- Segundo que transformemos los nombres de los import realizados en el archivo my-element.js, para usar la ruta en lugar del nombre del package.
Este segundo punto es de vital importancia y requiere alguna explicación extra.
Imports con los nombres de los paquetes
En LitElement, en Polymer 3 y en todos los frameworks modernos (Angular, React, Vue…), los desarrolladores usamos los nombres de los packages en lugar de las rutas. Sin embargo, el navegador solamente entiende nombres de rutas para hacer imports y no sabe nada de nombres de los packages que tengan en npm.
Por ese motivo, si hacemos algo como
import { LitElement, html } from 'lit-element';
El navegador en principio no sabría qué importar, porque no hay nada en la ruta "lit-element" de nuestro proyecto. Esa carpeta está en "node_modules". Si indicásemos la ruta correcta hacia el módulo la definición de "LitElement" y "html" no tendría problemas, pero el caso es que estamos usando el nombre de la dependencia tal cual.
Ese es el motivo por el que nuestro servidor de desarrollo debe convertir los nombres de packages por sus rutas. Esto es algo que ya tenemos si usamos el servidor de desarrollo de WebPack, o de otra herramienta similar, pero todavía no tenemos nada de esto instalado en el proyecto.
Polymer CLI
Lo más cómodo para poder arreglar esta situación y contar con un servidor de desarrollo sencillo que nos haga las tareas que necesitamos, es instalar el Polymer CLI. El CLI son las herramientas por línea de comandos para desarrollar aplicaciones en Polymer. Tendremos que instalarlo si no lo hemos hecho antes:
npm install -g polymer-cli
Una vez instada de manera global esta herramienta, podemos lanzar el servidor de desarrollo, también desde consola, situados en la carpeta raíz del proyecto.
polymer serve
Una vez lanzado este comando, el servidor de desarrollo arranca y nos informan en la consola de la URL que tenemos que abrir para ver nuestro proyecto.
Accediendo con un navegador moderno a la URL proporcionada podremos ver nuestro primer componente en funcionamiento. Deberíamos ver el texto que aparecía en el template del componente: "Soy My Element".
Poyfill de WebComponents
Este ejemplo, tal cual, te funcionará en Chrome, Opera, Safari y Firefox. En este preciso instante no funciona en Edge o Internet Explorer 11, porque no tienen ya disponibles todas las partes del estándar Web Components. No es un problema, ya que tenemos un polyfill que nos ayudará, dando soporte a navegadores antiguos o poco actualizados.
Para instalar el Polyfill tenemos que lanzar el comando:
npm install @webcomponents/webcomponentsjs
Ahora, en el index.html, antes de colocar el SCRIPT de nuestro componente, tenemos que enlazar con el polyfill.
<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
Para no dejar lugar a dudas, el código completo de nuestro index.html sería este:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ejemplo con LitElement</title>
<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script type="module" src="src/my-element.js"></script>
</head>
<body>
<my-element></my-element>
</body>
</html>
Ahora, gracias a haber añadido el script de webcomponentsjs, el navegador tendrá toda la base necesaria para entender nuestro custom element. Por supuesto, el polyfill es suficientemente inteligente para que se carguen aquellos polyfill que sean necesarios según las características de cada navegador. Si no necesita Polyfills simplemente no cargará ningún archivo.
Si arrancamos el ejemplo en un navegador Edge, que sí necesita polyfills aún en el momento de escribir este artículo, podremos verlo en funcionamiento perfectamente.
Conclusión
Hemos visto cómo crear un componente sencillo, usando LitElement como clase base. De momento es un elemento que simplemente muestra un texto en pantalla, aunque más adelante podrá convertirse en algo más complejo.
Como has podido observar, el hecho de usar LitElement no revierte ninguna dificultad, lo más especial es que necesitamos contar con un servidor de desarrollo que nos permita ver el proyecto en marcha, o producirlo para poner en el servidor definitivo. Este paso resultará familiar para cualquier desarrollador frontend experimentado y no difiere en nada de lo que puedas conocer o usar para cualquier framework, pero si eres nuevo en este mundo quizás te parezca algo más complejo el hecho de tener que usar tantas herramientas desconocidas. Si es el caso, no te preocupes, porque con un poco de tiempo podrás familiarizarte con todo esto.
Lo bueno de nuestro componente es que lo podemos usar allá donde se necesite. Su base es puramente Javascript y por tanto, una vez cargado el componente, es como cualquier otra etiqueta HTML y lo podremos usar en un sitio web común o una aplicación web desarrollada con Javascript "vanilla" o con cualquier framework existente.
En la siguiente entrega del Manual de LitElement podremos comenzar a estudiar los templates más a fondo, su método render y alguna de la sintaxis más básica para hacer binding de datos y eventos.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...