Me ha pasado en varias ocasiones la necesidad de re-utilizar un componente en varios proyectos. ¿La solución? Copiar-pegar el componente y llevármelo al proyecto que lo necesite, y tal vez, ajustar alguna cosa para que funcione. ¿Te suena?
Artículo original: Crear WebComponents con StencilJS y reutilizarlos en diferentes proyectos
Tal vez esto te funciona cuando el componente en cuestión, por ejemplo un botón, te lo llevas de un proyecto React a otro proyecto React, pero... ¿qué haces si un proyecto es de React, otro de Angular u otro de Vue? Tocaría re-hacer ese botón para cada proyecto. Es decir, estarás haciendo tres veces la misma funcionalidad. No suena bien, ¿no? 💩
Bueno, si te sientes identificado/a con ésta situación, me alegro de no ser el único.
¿Qué tal te suena si hacemos ese mismo botón una sóla vez y lo aprovechamos para nuestros proyectos? Venga, vamos a ello.
Índice de contenidos
- Introducción
- ¿Qué es StencilJS?
- Crear un proyecto con StencilJS
- Creación de un componente botón reusable con StencilJS
- Añadir estilos CSS a un webcomponent
- ¿Cómo ver un webcompoent creado con Stencil?
- Generando la distribución
- Distribuir nuestro webcomponent en un package de Github
- Integración en un proyecto con React
- Integración en un proyecto con Vue
- Conclusiones
Introducción
En este artículo vamos a ver con un ejemplo práctico cómo implementar un componente con StencilJS (el botón comentado anteriormente), lo publicaremos como un package
en Github y luego lo integraremos en nuestras aplicaciones, haremos una prueba de integración en Vue y otro en React. ¿Suena bien? ¡Al lío!
¿Qué es StencilJS?
StencilJS es una herramienta de los creadores de Ionic, que definen como «El generador mágico de web components reusables». Es decir, StencilJS permite crear de forma sencilla y sin grandes esfuerzos web components nativos.
Crear un proyecto con StencilJS
Lo primero que haremos, como es obvio, crear el proyecto, muy fácil:
npm init stencil
Lo que automáticamente nos preguntará que tipo de proyecto es:
Nos salen tres opciones de tipos de proyecto. Vamos a seleccionar la opción component
ya que lo que queremos crear es una colección de componentes. Como nombre del proyecto pondremos custom-components-stencil
(por ejemplo):
Perfecto, ya hemos creado nuestro primer proyecto con Stencil 🚀, ahora abrimos el proyecto con nuestro IDE favorito y empezamos:
cd custom-components-stencil
npm install
npm start
Bien, una vez arrancado el proyecto nos dirá la URL en la que está funcionando nuestro ejemplo, en mi caso en http://localhost:3333/
donde veremos un ejemplo básico que nos ofrece por defecto StencilJS.
Creación de un componente botón reusable con StencilJS
Llegados a este punto tenemos ya instalado nuestro primer proyecto StencilJS. Ahora vamos a crear nuestro primer webcomponent de tipo botón reusable.
Lo primero, nos fijaremos en el archivo src/index.html
donde veremos que Stencil ya nos ofrece un ejemplo de uso de un componente llamado my-component
, pégale un vistazo a la carpeta src/components/my-component
que es donde está definido. Básicamente es un div que recibe tres props (first, middle, last) y los pinta por pantalla.
Bien, vamos a crear nuestro componente. Seguiremos los siguientes pasos:
- Creamos a carpeta dentro de
src
que llamaremosat-button
(at es de Alex Tomás 😜) - Dentro de
src/components/at-button
creamos un archivo con formato .tsx que llamaremosat-button.tsx
ya añadimos lo siguiente:
import { Component, Prop, h } from '@stencil/core';
@Component({
tag: 'at-button',
styleUrl: 'at-button.css',
shadow: true,
})
export class ATButton {
@Prop() text: string;
render() {
return <button class='button'>{this.text}</button>;
}
}
Bueno, bueno, esto son muchas cosas, pero que no cunda el pánico. Veamos cuales son las partes del componente:
- Decorador
@Component
es donde especificamos el nombre del componente y su fichero de estilos. - La
@Prop
text va a ser la propiedad que le enviaremos al componente. Estas propiedades por defecto son inmutables desde dentro del componente. Para hacerlas mutables hay que anotarlas con@Prop({ mutable: true })
, pero no va a ser el caso. - El método
render
, que devuelve la descripción necesaria para pintar el componente. Cómo verás usamos sintaxis JSX. Si no conoces JSX pásate por este enlace de la documentación de React que explica qué es JSX.
Recuerda crear el fichero de estilos en
src/components/at-button/at-button.css
Añadir estilos CSS a un webcomponent
Muy sencillo. Al añadir en el decorador @Component
el nombre del archivo CSS, añadimos las clases que queramos. En nuestro caso le hemos añadido la clase button
a nuestro botón. Por lo tanto, le añadimos un estilo básico (recuerda que estamos aprendiendo la funcionalidad de los webcomponentes, no en la estética 🙃):
.button {
background-color: teal;
border-radius: 30px;
border: none;
box-shadow: 2px 2px 9px 2px rgba(0, 0, 0, 0.28);
cursor: pointer;
padding: 10px 30px;
color: white;
}
.button:hover {
background-color: rgb(0, 146, 146);
}
Vale, perfecto. ¿En qué punto estamos?
- Hemos iniciado el proyecto con Stencil.
- Tenemos un webcomponent creado que se llama
at-button
. - Le hemos dado estilos css.
¿Y ahora como lo puedo ver?
¿Cómo ver un webcompoent creado con Stencil?
Recuerda, que al principio del artículo, al crear el proyecto teníamos el comando npm run start
o npm start
para ver el proyecto en nuestro navegador. Vale, pero antes vamos a editar el fichero src/index.html
y lo dejaremos de la siguiente manera:
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0"
/>
<title>Stencil Component Starter</title>
<script
type="module"
src="/build/custom-components-stencil.esm.js"
></script>
<script nomodule src="/build/custom-components-stencil.js"></script>
</head>
<body>
<at-button text="¡Hola mundo!"></at-button>
</body>
</html>
Si vamos a nuestro localhost que nos indica Stencil al arrancar el proyecto deberíamos ver nuestro botón:
Generando la distribución
¡Ya tienes tu primer webcomponent creado con StencilJS! ¿Y hora como lo vamos a usar en otros proyectos? Lo primero que tenemos que hacer, es compilar todo:
npm run build
Lo que te debe generar la carpeta dist
y loader
. Perfecto, vamos a crear nuestro package
en Github.
Distribuir nuestro webcomponent en un package de Github
Lo primero que necesitaremos será tener creado un repositorio, si no lo tienes creado, hazlo (no voy a detenerme en como crear un repo y en subir los cambios en él ya que no es el objeto de este artículo 😌).
En mi caso el proyecto estará público en la siguiente URL: https://github.com/alextomas80/stencil-webcomponents
Perfecto. Ya tengo mi proyecto compilado y subido a Github. Ahora vamos a crear nuestro package.
Generar token en Github para crear un package
Aquí vien un poco de magia. Lo primero que necesitamos es un archivo llamado .npmrc
donde añadiremos lo siguiente:
//npm.pkg.github.com/:_authToken=TU_TOKEN
registry=https://npm.pkg.github.com/USUARIO
En mi caso será:
//npm.pkg.github.com/:_authToken=d7a031caf35....🤫
registry=https://npm.pkg.github.com/alextomas80
Para crear un token para publicar un package en tu repositorio necesitarás acceder en Github a Settings > Developer settings > Personal access tokens
Y necesitaremos hacer un cambio en nuestro package.json
:
{
"name": "custom-components-stencil"
}
Lo cambiaremos por nuestro usuario y nombre que le hayas puesto a tu repositorio, en mi caso quedaría de la siguiente forma:
{
"name": "@alextomas80/stencil-webcomponents"
}
Bien, tenemos todo listo, ahora sí, para enviar nuestro package a Github 🤞🏻
npm publish --access public
Y deberíamos de obtener una respuesta similar a ésta:
¡Sí! ¡Ahora sí! Tienes tu package creado con éxito. ¿Cómo comprobarlo? Accede a la URL de tu repositorio terminado en packages
: https://github.com/alextomas80/stencil-webcomponents/packages
Integración en un proyecto con React
Es hora de ver que todo esto ha servido para algo y funciona. Vamos a utilizar nuestro webcomponent at-button
en un proyecto que vamos a crear con react de una forma rápida. No me voy a entretener mucho con esto:
Creamos nuestro proyecto de ejemplo:
npx create-react-app test-with-react
Arrancamos el proyecto y veremos la pantalla de bienvenida típica de React:
npm run start
Ahora instalemos nuestro package con nuestro webcomponent. Si volvemos a Github y consultamos nuestro package veremos que nos indica como podemos instalarlo.
Así que usaremos NPM para ello:
npm install @alextomas80/stencil-webcomponents@0.0.1
Bien. Ahora vamos a usarlo. Para ello vamos a pegar un vistazo a la documentación de Stencil para la integración con React, es muy sencillo, yo te lo resumo:
Abrimos el archivo src/index.js
y lo dejamos de la siguiente manera:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
// Importamos nuestro package que hemos creado en los anteriores pasos
import {
applyPolyfills,
defineCustomElements,
} from '@alextomas80/stencil-webcomponents/loader';
ReactDOM.render(<App />, document.getElementById('root'));
applyPolyfills().then(() => {
defineCustomElements();
});
Y ahora sí, por fin, vamos a usar y ver nuestro at-button. Abrímos el archivo src/App.js
y añadimos nuestro botón de la siguiente manera:
<at-button text="Mi WebComponent en React" />
Con lo que veremos, por fín, nuestro botón de la siguiente manera y estilo:
¡Bien! Como verás tiene el mismo estilo que le dimos al componente cuando lo creamos con Stencil. Y además le podemos pasar la propiedad text
para definir el texto que tendrá el botón. Una maravilla. Pero... ¿no habíamos dicho que el fin de este artículo es el de crear un componente y usarlo en React y Vue?
Integración en un proyecto con Vue
Creamos nuestro proyecto de ejemplo Vue:
vue create test-with-vue
Seleccionamos las opciones que nos pide (versión de Vue, etc etc, no me voy a entretener en esta parte). Arrancamos el proyecto y veremos la pantalla de bienvenida típica de Vue:
npm run serve
Y vamos a hacer exactamente lo mismo que con ejemplo de React. Vamos a instalar nuestro package con NPM:
npm install @alextomas80/stencil-webcomponents@0.0.1
Vamos a pegar un vistazo de nuevo a la documentación de Stencil para la integración con Vue, también es muy fácil y muy similar a React:
Abrimos el archivo src/main.js
y lo dejamos de la siguiente manera:
import { createApp } from 'vue';
import App from './App.vue';
// Importamos nuestro package que hemos creado en los anteriores pasos
import {
applyPolyfills,
defineCustomElements,
} from '@alextomas80/stencil-webcomponents/loader';
applyPolyfills().then(() => {
defineCustomElements();
});
createApp(App).mount('#app');
Y ya podemos usarlo. Para ello vamos al archivo del ejemplo src/App.vue
y añadimos:
<at-button text="Mi WebComponent en Vue" />
¡Y ahí tenemos de nuevo exactamente el mismo botón!
Conclusiones
Con este sencillo ejemplo has podido ver y probar el potencial que nos ofrece Stencil y las posibilidades que nos brinda. Podemos crear componentes rápidamente y completamente reutilizables en cualquier tipo de aplicación ya sea de una u otra tecnología, o incluso sin que tengan uns framework JavaScript por detrás como hemos hecho.
Así pues, si lo que quieres es tener tu libraría de componentes, compartirla con diferentes proyectos y además trabajar en ellos diferentes compañeros de equipo... te recomiendo totalmente su uso.
Y esto es todo. Espero que te pueda servir 😉
Top comments (1)
¿Funciona dentro de un formulario para los tipos reset y submit? Saludos