Cuando trabajamos con Web Components, una de las cuestiones que más suele generar debate es cómo manejar las plantillas HTML dentro de los componentes. La API slot y el uso de templates para rellenar el Shadow DOM son herramientas muy útiles, pero no están exentas de críticas. Por ejemplo, muchos desarrolladores acostumbrados a frameworks como React, que utilizan JSX, pueden encontrar incómodo tener el HTML, JavaScript y CSS separados en distintos archivos o lugares. Incluso soluciones como Vue, que agrupan template, estilo y script en un único archivo .vue, pueden parecer más organizadas en comparación.
Una alternativa sencilla para evitar tener el template en un archivo HTML separado es usar strings multilínea en JavaScript. Gracias a las comillas invertidas (backticks), podemos definir un template completo como un string dentro del propio archivo JavaScript del componente. Esto nos permite asignar ese string directamente al innerHTML del Shadow DOM, manteniendo el código más compacto y accesible. Además, en entornos con herramientas como webpack, existen loaders que permiten importar archivos HTML como strings o nodos, facilitando aún más esta integración. Tecnologías como HTML Modules, que están en evolución, también apuntan a mejorar esta experiencia.
Sin embargo, Web Components por sí solos pueden quedarse cortos en proyectos más complejos o cuando buscamos una experiencia similar a la que ofrecen frameworks completos. Por eso, existen microframeworks que nos acercan al concepto de JSX sin necesidad de usarlo directamente. Un ejemplo destacado es HyperHTML, que permite embeber HTML dentro de JavaScript usando interpolación de strings. Aunque tiene su propia sintaxis y curva de aprendizaje, ofrece polyfills para funcionar incluso en navegadores antiguos como IE9.
En la misma línea, el proyecto Polymer ofrece litHTML, que también facilita la composición de templates mediante interpolación HTML. Sobre litHTML se construye litElement, una microlibrería que permite crear custom elements extendiendo litElement en lugar de HTMLElement. Esta API es distinta a la tradicional, usando decoradores y una forma más declarativa de definir propiedades, estilos y templates, lo que ayuda a mantener el CSS y el HTML encapsulados dentro del componente.
Un punto importante a considerar cuando usamos templates dentro de componentes es evitar que estos sean demasiado grandes. Si un template crece mucho, probablemente no estamos dividiendo bien nuestra aplicación en componentes más pequeños y manejables. Este problema es común en React, donde la solución habitual es crear múltiples componentes para dividir la interfaz. Lo mismo aplica para Web Components, Vue o cualquier otra tecnología similar. Por ejemplo, si estamos creando una barra lateral (sidebar), lo ideal es tener un componente para la barra, otro para el desplegable, otro para los iconos, y así sucesivamente. Esto facilita la organización y el mantenimiento del código.
Además, podemos incluir el CSS dentro del propio string del template usando etiquetas <style>, lo que permite mantener el estilo junto con el HTML y el JavaScript del componente. Esta técnica es compatible con litElement y otras microbibliotecas, y evita tener archivos CSS separados que compliquen la estructura.
Si buscamos algo más avanzado, existen microframeworks como Svelte, que se asemeja a Vue en cuanto a la organización en archivos que contienen script, estilo y template. La diferencia principal es que Svelte no monta un runtime en el navegador; en cambio, compila los componentes a HTML y JavaScript estándar durante la construcción, lo que resulta en aplicaciones más ligeras y eficientes. Svelte también soporta componentes anidados, lo que facilita la creación de interfaces complejas sin la sobrecarga de un framework completo en tiempo de ejecución.
Otra alternativa interesante es Stencil, que también compila Web Components y utiliza una sintaxis parecida a JSX, aunque con diferencias. Stencil genera archivos .tsx y permite definir atributos y renderizar HTML de forma declarativa, ofreciendo una experiencia cercana a la de frameworks modernos pero enfocada en Web Components.
En definitiva, aunque Web Components tienen ciertas limitaciones, existen múltiples opciones para mejorar la experiencia de desarrollo sin necesidad de adoptar frameworks completos. Podemos optar por strings multilínea para templates simples, microframeworks como HyperHTML o litHTML para una interpolación más potente, o herramientas más avanzadas como Svelte y Stencil para proyectos que requieran mayor organización y rendimiento, siempre manteniendo la cercanía con el JavaScript nativo y evitando dependencias pesadas.