Creando un generador de plantillas con EJS
Tue Sep 10 2024
Cuantas veces no hemos tenido que estar creando una y otra vez, archivos de componentes, archivos para las pruebas unitarias o bien cuando estamos implementando un patrón de arquitectura y necesitamos generar múltiples archivos o carpetas para poder seguir un mismo orden. En ocasiones esto se vuelve tedioso o bien muy tardado de hacer, aun por poco tiempo que nos tome realizar dicha actividad.
El día de hoy comparto contigo un poco acerca de una, de quizá múltiples opciones, para poder generar estos archivos y directorios de forma fácil y dinámica; por medio de Javascript y una dependencia sencilla llamada EJS
Hace algunos años trabajando con angular y su CLI, me encontré entre varios repos, husmeando el código para ver como era cierta lógica del momento, entre eso me encontré con la forma en la cual interpretaba la CLI los comandos y a su vez está generaba los archivos. Recuerdo que es su momento un dev con el que estaba trabajando había realizado un servicio en una API en JS para poder crear platillas de correos electrónicos y rellenarlos con información dinámica.
El me mencionó que herramienta usaba y como lo hacia. Después al encontrarme con el código de la CLI de angular fue más fácil comprender su funcionamiento. Y hace algunos años cuando comencé a trabajar con Vue JS, resultaba que la CLI que tenía el mismo framework era muy limitada. Ahora que ya me veo en la necesidad de poder interactuar con más proyectos y a su vez aplicar algo de patrones o arquitectura pues es necesario cubrir ciertos puntos o características clave como lo son:
- La organización de las carpetas/archivos/componentes/etc..
- La implementación y aplicación un tanto rigurosa de pruebas unitarias y demás
- La posible y próxima implementación de arquitecturas o estructuras organizacionales de directorios
Entonces para esto, creo que es una buena y sencilla idea; el proporcionar una herramienta que sea flexible, fácil de extender, de usar y que proporcione una forma de crear dichas organizaciones, siguiendo algún estándar o convención. Que no solo sirve para mi o para los devs con los que trabajo sino con todas aquellas personas que se encuentren con las mismas necesidades.
Al final de este artículo dejo en enlace a la herramienta que se desarrollo en este contenido. Principalmente es un CLI pero también se puede usar como módulo al instalarse u usar directamente el generador
El objetivo
Quizás te habrás encontrado en algún momento con CLIs que te generan scaffolds de proyectos desde 0, que te generan componentes, estructuras organizacionales de ficheros, etc.. Algo similar a como lo hace angular con su comando ng generate component xxxxxxxx
ó quizá con algo como create-vue
o create-react-app
Entonces vamos a ver como generarlos, cabe agregar que esta forma es quizá una de muchas que existen y que podrían ser de ayuda no solo como conocimiento sino también para comprender como funcionan under the hood algunas de las características como las que describimos antes.
La idea aquí es poder generar archivos para componentes de vue y archivos de test que nos ayuden a siempre tener generados estos en el proyecto.
El proceso
Como ya mencioné anteriormente, esto se puede lograr con EJS de una forma sencilla y que al final del artículo; no solo comprenderás como funciona sino también el como poder extender una funcionalidad del mismo código que verás aquí y el poder utilizar esta dependencia que vamos a explicar.
Definir los archivos a crear
Lo principal es saber y tener bien definido: que es lo que vamos a estar creando, junto con su formato, extensión y contenido, para este caso lo único que se necesitaba era un componente de vue vacío y la definición de un archivo de pruebas unitarias con su respectivo formato.

Obviamente todo esto es genérico y está en blanco para poder llenarlo, según el caso que necesitemos. Ahora lo siguiente será, literalmente copiar este contenido y llevarlo a un archivo .ejs
y poder modificarlo de acuerdo con las necesidades de cada archivo y/o caso de uso.
Quedando de la siguiente forma, para este caso en especifico:

Conocer el ruta de la ubicación de las plantillas
Para comenzar, nosotros ya tenemos que haber creado las plantillas y definido en donde las vamos a guardar dentro de la maquina o dentro de la misma organización de los archivos, para este caso se almacenaron en la siguiente ruta: /assets/templates/
y para hacer referencia a ellas desde el código, se hizo uso del módulo nativo de NodeJS: path
Primero necesitamos conocer la ruta actual del directorio de donde se está ejecutando el código, esto se logra por medio de la variable global __dirname
, además de conocer la ruta relativa de donde se encuentran las plantillas en relación a nuestro archivo y ambas las unimos por medio de la función join
:

En nuestro caso, el código resultó como se muestra en la imagen.
Como generar los archivos
Una vez que ya tenemos la ruta de donde se encuentran nuestras plantillas, los siguientes pasos serían:
- Leer las plantillas
- Renderizarla
Para leer las plantillas, ya tenemos la ruta de las mismas; entonces lo siguiente es leer como tal esos archivos. Y esto se logra por medio de la función readFile
o readFileSync
. Para este caso, creo que fue más conveniente realizar la lectura de forma síncrona y el código quedó de la siguiente forma:

Esto básicamente lo que hace es leer el archivo con extensión .ejs
en un formato de codificación utf-8
, estándar para los caracteres que se interpretarán y por último le pasamos un flag
para decirle que sea de solo lectura.
Esto nos devolverá el contenido del archivo en una cadena de texto (string
).
Ahora para poder renderizar el contenido, refiriéndonos a esta parte al proceso de agregar los datos de forma dinámica al contenido, lo podemos hacer de varias formas, puedes consultar la documentación oficial de EJS para saber más al respecto, pero en este caso usamos la función render
para lograrlo, quedando de la siguiente forma:

Aquí como se puede observar, se le pasa como primer parámetro el contenido que previamente se había obtenido de la plantilla, es decir: un string
. Seguido de la variable data
, que es sencillamente un objeto con todos los datos que se requieran pasar al archivo y que estos se puedan interpretar por medio de EJS para plasmar la información de forma dinámica.
Por último, docContent
, tendrá en este caso un string
con el contenido de plantilla pero sin variables, estás se reemplazarán por el contenido respectivo gracias a EJS. Y este será el contenido que pondremos al escribir nuestro archivo.
Conocer la ruta a donde se van a generar los archivos
En nuestro caso la CLI necesita que se defina un nombre al componente; pero también no solo se puede establecer el nombre y ya, sino que también se puede agregar la ruta de salida en la misma definición. Y para conocer dicha ruta se puede hacer uso de:
process.cwd()
– Para conocer el directorio actual de ejecución
resolve()
– Para poder obtener la ruta absoluta de acuerdo a algún parámetro que se nos pase y/o de acuerdo al valor de cwd()
Resultando en nuestro caso, de la siguiente forma:

Con esto ya tenemos tanto la ruta absoluta de donde se generará el archivo, como el nombre incluido. Y como normalmente lo último que se agrega es el nombre de lo que se requiere crear, se puede obtener no solo la ruta sino este último también. Quedando la lógica de la siguiente forma:

Generar los archivos en la ruta dada
Para terminar, ya solo nos falta generar los archivos con el contenido. Y esto lo podemos lograr por medio de la función writeFile
o writeFileSync
. Además de que si por cualquier cosa existe una anidación de directorios, y para evitar problemas: específicamente en entornos Windows, se puede hacer uso de las funciones existsSync
y mkdirSync
respectivamente.
Quedando el código de la siguiente forma de acuerdo a nuestro caso de uso.

En donde primero validamos que el directorio exista, ya que si no existe pues que se cree y de forma recursiva si es que hay directorios anidados, es decir; un directorio dentro de otro directorio y así sucesivamente. Y por último se crea el archivo pasándole la ruta de destino más el nombre de la plantilla y la extensión que se requiere, además de que se le pasa el contenido procesado previamente por EJS y finalmente se define la codificación que se va a aplicar al archivo.
Y finalmente aquí te comparto la dependencia final en la que estaba trabajando pero que expone el generador, me he dado cuenta de que falta algo de documentación al respecto pero la agregaré en el proceso, aunque también son bienvenidas las contribuciones

Referencias
- Packages/angular/cli at main · angular/angular-cli. (s/f)
- create-vue: 🛠️ The recommended way to start a Vite-powered Vue project. (s/f).
- EJS — embedded JavaScript templates. (s/f). Ejs.Co. Recuperado el 26 de agosto de 2024, de https://ejs.co/
- Global objects. (s/f). Nodejs.org. Recuperado el 26 de agosto de 2024, de https://nodejs.org/api/globals.html
- Path. (s/f). Nodejs.org. Recuperado el 26 de agosto de 2024, de https://nodejs.org/api/path.html
- File system. (s/f). Nodejs.org. Recuperado el 26 de agosto de 2024, de https://nodejs.org/api/fs.html
Al final de este artículo vienen los medios por los cuales puedes seguir lo que voy publicando. Espero te haya gustado esta pequeña experiencia y pato-aventura de un día en el desarrollo.
Happy coding 🖖