Componentizando frente a un CMS: PugJS (1/2)

No descubrimos nada nuevo si decimos que el desarrollo front-end está actualmente orientado a la componentización.

La inclusión de web components y SPAs como tecnologías potentes en cualquier proyecto front y la popularidad de frameworks JS basados en este concepto (ReactJS, VueJS, Angular…) hacen que prácticamente todos los desarrolladores front estemos aprendiendo estas tecnologías.

Y desde luego, el concepto funciona. Nuestra vida se vuelve más fácil, nuestro código más sencillo y más corto, evitamos duplicarlo… Y somos más felices, ¿verdad?

Digo esto porque después nos encontramos con la realidad y nos baja de golpe del plano de la fantasía.

La tecnología front avanza más rápido de lo que lo hacen muchas de las aplicaciones actuales y, mientras que a todos nos gustaría formar parte de estos modernos ecosistemas, nos encontramos con proyectos que no han podido evolucionar y cuyo stack tecnológico nos resulta muy familiar.

Enormes sites estáticos, aplicaciones multipágina, aplicaciones cuya lógica es gestionada por CMS y… código JQuery.

Fuente: @_mat3e_

Ya sabes lo que va a pasar a continuación. Este proyecto lleva ya tiempo funcionando en producción. No hay muchos bugs y en el código, más o menos limpio, han aplicado buenas o malas prácticas.

Pero resulta demasiado costoso en tiempo y esfuerzo evolucionar sus tecnologías. Puede que la arquitectura sea bastante simple (o prácticamente no haya arquitectura).

Puede que el front sea únicamente maqueta y toda la lógica se implemente mediante un CMS, realizando en muchas ocasiones la comunicación front-back mediante etiquetas y no mediante una API que podamos consumir.

Y tú has aprendido una serie de conceptos más avanzados que da miedo aplicar en estas situaciones, porque refactorizar a este nivel implica un todo o nada.

Se añade también la dificultad de justificar semejante cambio de algo que está funcionando en producción, sobre todo si no existe la necesidad de mejorar el rendimiento de la aplicación. ¿Cuántas veces hemos escuchado la frase está bien tal y como está”?

No obstante, defendemos que modernizar una aplicación en estas condiciones sin duda supone mejorar el producto y, aunque requiera un gran tiempo de desarrollo inicial, las arquitecturas de componentes pasan a ser muchísimo más estables y los desarrollos muchísimo más ágiles, alargando la vida del producto.

Por supuesto, es indiscutible la cantidad de ventajas a nivel de potencia que aportan aplicaciones SPA, PWA, etc.

Si estás entre esos desarrolladores anclados a un proyecto heredado de estas características, todavía hay esperanza para ti.

Veamos dos caminos diferentes para componentizar una aplicación estática basada en HTML + Vanilla JS/JQuery permitiendo la integración en un CMS. Y lo mejor es que podremos hacer la conversión poco a poco.

PugJS al rescate

Si llevas tiempo desarrollando en tecnologías web, puede que hayas oído hablar de JadeJS. Aunque ha cambiado de nombre por motivos legales, sigue funcionando y su utilidad sigue presente hoy en día, tanto que todavía muchos desarrolladores apuestan por utilizarlo en sus aplicaciones.

Incluso los principales frameworks mencionados soportan este lenguaje. PUGJS sigue vivo y viene a ayudarnos en la encrucijada del mundo front.

¿Pero es una broma? ¿Una librería con este nombre? ¡No es ninguna broma! PugJS es un sistema de templates con una sintaxis propia que permite añadir lógica a nuestro HTML.

Mediante una tarea de compilación en Grunt/Gulp o Webpack podremos precompilar nuestras templates *.pug a documentos HTML en el proceso de empaquetado de la aplicación, y desplegar nuestra aplicación en un servidor de estáticos.

Tiene una pega (aunque puede ser una pega subjetiva dependiendo del desarrollador) ya que se trata de un lenguaje indentado.

Sintaxis en PugJS

Una de las ventajas de utilizar PugJS es que va a permitir dar el paso a componentizar de forma muy rápida y sencilla, tanto si eres desarrollador javascript como maquetador, ya que realmente estamos escribiendo código HTML pero sin la nomenclatura de tags.

Así, las etiquetas <div>, <p>, <span>, etc… pasan a ser simplemente div, p y span. A su vez, en lugar de usar class e id usaremos los caracteres ‘.’ y ‘#’. Y los atributos podemos escribirlos de la misma forma que en HTML, aplicando paréntesis.

Veamos un ejemplo de código pug, teniendo en cuenta además que las etiquetas div se pueden omitir para facilitar la lectura.

Además de abreviaciones en la sintaxis, PugJS nos permite dotar a nuestro HTML de lógica que nos permita simplificar nuestro código. De esta forma, podemos utilizar nuestras dotes de Javascript para potenciar el código.

Recordemos que Pug será precompilado a HTML, por lo que esta lógica no se ejecutará en el cliente final, sino en el proceso de empaquetado.

Las principales características que nos da Pug son:

  1. Bucles y condiciones if, else, for...
  2. Interpolación de variables y propiedades dentro de cualquier cadena.
  3. Gestión de dependencias de otros componentes pug e inyección de fragmentos de código mediante includes.
  4. Herencia y bloques de código modularizados.
  5. Mixins.

Pero entonces… ¿cómo componetizamos?

Si os habéis fijado bien en el ejemplo anterior, ya aparece la invocación a un componente llamado buttonPrimary.

PugJS nos entrega la funcionalidad de mixins, con los que podremos definir fragmentos de código que podemos invocar desde otros componentes y/o páginas.

A su vez, podremos pasar propiedades a estos componentes, pudiendo crear así un árbol de componentes estáticos en nuestra aplicación. Veamos un ejemplo de un componente por dentro.

La propiedad block nos permitirá introducir fragmentos de código dentro de un componente en su invocación, por lo que podremos crear también componentes envolventes.

En el siguiente ejemplo, en lugar de asignar el contenido del botón a la propiedad buttonText, este contenido será inyectado desde el lugar donde se invoca el componente.

Veamos un ejemplo más completo de un panel lateral que envuelve un contenido html genérico. Si nos fijamos en la propiedad &attributes podemos ver que nos servirá para propagar atributos HTML entre componentes.

Este componente a su vez llama al componente primaryButton, creando así un componente padre con un hijo. De esta forma podemos ir definiendo nuestro árbol de componentes Pug.

A continuación, escribamos una lista que renderice N veces un mixin card. Para ello, el carácter ‘-’ nos permitirá escribir código JS dentro de nuestro fichero Pug.

Este código no aparecerá en el fichero HTML compilado, pero nos permitirá realizar acciones más avanzadas.

Ventajas e inconvenientes

Resumiendo, aplicar PugJS en nuestra aplicación nos permitirá:

  1. Componentizar nuestro HTML y dotarlo de cierta lógica de renderizado, evitando duplicidad de código.
  2. Llevar a cabo el proceso de componentización poco a poco, ya que pueden convivir en el mismo proyecto páginas HTML y Pug.
  3. Precompilar en el proceso de empaquetado a HTML, por lo que podremos seguir integrando las templates generadas en un CMS.
  4. Mínimo riesgo de refactor de la aplicación ya que no supondrá cambiar ni una sola línea del código JS existente.
  5. Integración a futuro de los componentes en Pug en un framework JS como Angular o Vue.
  6. Integración con NodeJS.

¿Merece la pena entonces? Como inconvenientes encontramos:

  1. No mejora el rendimiento ni la potencia de la aplicación en sí. El código final sigue siendo HTML con el JS ya existente.
  2. Es un lenguaje indentado, si el tamaño de un fichero crece puede ser difícil su lectura. Aunque este aspecto puede ser subjetivo.
  3. No aporta nada más que facilidades a la hora de escribir HTML y un mecanismo sencillo de componentización.

Como opinión personal, es una herramienta que se queda corta en un proceso de componentización, pero si la situación del proyecto no permite introducir una pieza más avanzada (sea por lógica de un CMS o por riesgos), puede facilitarnos muchísimo la vida y permitirnos construir una completa librería de estilos y componentes para nuestras aplicaciones.

¿Qué más podemos hacer para componentizar en un CMS?

Si nuestro refactor implica conseguir más potencia y el proyecto puede asumir un desarrollo mayor, en el siguiente post hablaré de cómo podemos aplicar el mismo concepto de pre-renderizado en una aplicación con componentes VueJS.

Si tienes alguna propuesta o te has enfrentado a problemas similares, déjanos un comentario y cuéntanos cómo sobreviviste a un CMS.

Referencias y enlaces

Ingeniero de Imagen y Sonido reconvertido a desarrollador front. Tras la carrera entré en el mundo de la consultoría y encontré mi pasión en la tecnología Front y en Javascript. Músico de segunda profesión, mi tiempo fuera de la oficina lo ocupan mis guitarras, mi banda y la producción musical.

Ver toda la actividad de Javier Carceller

Escribe un comentario