Procesando hojas de estilo con Tailwind por medio de Vite

By   Skrigueztep Skrigueztep Wed Aug 21 2024

Antes de comenzar, me gustaría dar un poco de contexto, ya que la solución se basa principalmente en la implementación de un enfoque funcional.

En un proyecto algo grande en el que estoy trabajando, usamos Vue 3 + TailwindCSS + Vite y dado que también agregamos o nos vemos en la necesidad de agregar clases CSS personalizadas para nuestro uso, optamos por no solo compilar los estilos de los componentes, como se hace habitualmente; sino que también por procesar dicha hoja de estilos. Pero a la hora del desarrollo se dio que requerimos pasar por una parte de construcción, de dicho proyecto para poder hacer uso de él (lo que comúnmente llamaríamos build) y en este proceso generar una hoja de estilos por medio de Tailwind.

El detalle está en que para facilitar, un poco la Experiencia de Desarrollo (DX), se comenzó a utilizar esté proceso para realizarlo a la hora de detectar cambios en cada archivo por medio de vite build --watch, pero para ello tenemos varias alternativas las cuales te comparto a continuación

Estado actual

Inicialmente contábamos con los siguiente:

Es decir, tenemos configurado vite y tailwind, de la siguiente forma:

Como podemos ver, tenemos que al realizar el proceso de construcción: se ejecuta vite build && tailwind -i xxx -o xxx

Lo que esto significa es que al terminar de forma exitosa el trabajo del script vite build, se tiene que ejecutar el script de tailwind, si el primer comando falla en el proceso, el script de tailwind NO se ejecuta pero si lo actualizamos para que al desarrollar se haga el build en cada cambio, resultaría de la siguiente forma:

vite build --watch && tailwind -i xxx -o xxx

Lo que pasa aquí es que este comando no tendría el mismo efecto que el anterior y JAMAS llegaría a ejecutarse el script de Tailwind, entonces como alternativas tenemos las siguientes opciones:

  • Usar el pre script de NPM
  • Usar el post script de NPM
  • Modificar la configuración de vite para poder ejecutar el comando de Tailwind en cada cambio detectado


Al usar la opción de --watch en el script de vite, lo que se hace es activar el HMR (Hot Module Reload) o Live Reload, esto provoca que la ejecución nunca termine y se observen los cambios en todo momento o hasta que matemos el proceso con Ctrl + C


Pre y Post script

En NPM por defecto, se pueden indicar ciertos comandos pre establecidos dentro de los cuales algunos se pueden “personalizar”, ya que como es este el caso; podemos agregar un script con un nombre que deseemos y también podemos agregar su pre y post: esto se logra y se ve de la siguiente forma:

El pre se ejecuta ANTES de la ejecución del comando al que hace referencia y posteriormente se ejecuta el comando propiamente dicho

El post es todo lo contrario, este se ejecuta DESPUÉS de que el comando principal de haya ejecutado satisfactoriamente


Resulta que estas primeras dos opciones no son del todo viables, ya que si lo ejecutamos con el pre, el script procipal (vite build --watch), se encarga de eliminar el directorio dist y por endé se eliminaría nuestra hoja de estilos que ya hemos procesado

Por otra parte, si fuese con el post script, tampoco funcionaría. Ya que como el script principal no se termina hasta que manualmente lo detenemos, obviamente ya no podríamos hacer uso de la hoja y jamas podríamos usarla


Modificar las configuraciones de vite

vite es una herramienta de tooling compatible con rollup y es muy pero muy personalizable, ya que podemos realizar ciertas configuraciones por medio de flags en la linea de comandos y bien en su archivo con configuración

Y el primer ataque fue justo ese… El modificar la configuración de construcción de alguna forma, para que cuando se realice la construcción y se observen los cambios exclusivamente; se pueda generar la hoja de estilos por medio de tailwind de forma casi automática. Y según la documentación, si se puede agregar ciertas modificaciones a la configuración de la construcción

Pero desafortunadamente es muy limitada y no nos brinda las opciones o la flexibilidad necesaria.

Buscando entre la documentación y San Google, nos encontramos en StackOverflow con una pregunta y una respuesta muy curiosa…

Entonces, de acuerdo con la esta información y parte de la referencia de la documentación oficial, podemos hacer uso de un plugin, básicamente sería crear un plugin personalizado para poder realizar este proceso.

Nos dimos a la tarea de comenzar el desarrollo pero oh sorpresa! 🤯🤯🤯… si bien el alcance en este caso no es tan limitado, lamentablemente no nos podía informar el mismo vite cuando se reactivaba el proceso de construcción por cambios en algún archivo.

Pero da la casualidad de que navegando entre las respuestas de Github, vite es tan flexible que no solo es:

  • Compatible con Rollup
  • También tiene una configuración bastante flexible
  • Se puede extender la funcionalidad o modificarla por medio de los plugins
  • También exponer algunas APIs como las siguientes:

Afortunadamente todo está bastante bien documentado y se expone una API de Javascript, con la cual también se puede jugar y hacer uso de varias cosillas, entre ello específicamente interactuar con el proceso de construcción para poder configurarlo y escuchar los eventos que vayan pasando.

Lo cual, aquí si podemos capturar cuando se reactiva la construcción por que se detectaron cambios.

La solución

Con este último enfoque y gracias a las preguntas que se fueron arrojando en Github, podemos ver de forma simple, el como interactuar con dicha API, ya solo faltaría limitar el funcionamiento por medio de algunas validaciones para cuando se realice la construcción y se observen los cambios a la vez. Ademas de poder procesar las hojas de estilo por medio de tailwind con su comando

Esto último no es tan complicado, si es que ya has tenido un poco de practica con las funcionalidades de exec y execSync que proporciona node. La solución final queda más o menos de la siguiente forma:

En donde podemos ver algunos de los comentarios que son clave para limitar el funcionamiento y para poder realizar la ejecución que queremos sin complicaciones ni propensión a fallos.


Como puedes observar, antes de realizar la ejecución del script; se hace una validación para determinar si el proceso de construcción ha finalizado y así poder tener la hoja de estilos ya procesada sin la preocupación de que vaya a ser eliminada por el mismo


Referencias