Archivo de la etiqueta: grunt

Aprendiendo Grunt a partir de Ant

Prólogo

Hace unos años, unos 8 ya …

[Grunt logo]En un proyecto me tocó realizar una ‘builtool‘. Era una herramienta común que utilizarían todos los demás proyectos no importando su tecnología, PHP,.Net, Java, etc. Obtenía el código del sistema de control de versiones compilaba, paquetizaba y subía la build compilada a otra rama del control de versiones. En realidad era un pre-Maven porque obligaba a una cierta estructura de directorios en los proyectos pero no tenía ni su control de dependencias, ni sus arquetipos para nuevos proyectos. La herramienta estaba hecha en Ant.

Realmente nunca me llegó a apasionar ese proyecto, siempre me ha gustado más programar. Pero me ayudó a tener conciencia de la importancia de saber montar el ‘Control de la configuración‘ de un proyecto y también, como podéis imaginar, a tener bastante soltura con Ant.

Capitulo I

… en la actualidad

Para el Front del nuevo proyecto, con mucha carga de JavaScript, teníamos que generar la build  y realizar el despliegue. Para hacer menos pesada y más rápida la descarga necesitamos comprimir html, jasvascript y css y en el caso de estos dos últimos unificarlos en un sólo fichero.  Este proceso también lo  utilizaríamos para hacer despliegue continuo en nuestro entorno de preproducción, utilizando Jenkins.

Grunt se ajustaba perfectamente a nuestras necesidades y además se unificaba las tecnologías. La elección de Grunt en vez de Gulp, otra herramienta similar, fue porque el primero está incluido en Yeoman, que viene a ser en Javascript lo que Maven es a Java. Una herramienta de gestión de dependencias, arquetipos, generación de buidls, test, etc.., que al igual que Maven permite gestionar todo el ciclo de vida de las builds. Elegí Grunt como un primer paso del camino que muy probablemente nos lleve a Yeoman.

Me enfrente al reto aprendiendo algo nuevo desde la perspectiva de algo conocido. Utilizando como punto de apoyo, sin que lo conocido conllevara  a perjuicios iniciales. Estas son las semejanzas, las diferencias y las conclusiones a las que he llegado.

En que se parecen…

Ant tiene ya mucho recorrido, o dicho de otra manera ya es bastante ‘viejuno‘. En cierta forma fue la respuesta de Java al Make de C. Surgió de la necesidad de crear una herramienta que pudiera compilar, generar ejecutables y que no dependiera del sistema operativo donde se ejecutara. Permite también la generación de test, despliegue, generación de documentación, etc.

Grunt está dentro del ecosistema Javascript, es un ‘ejecutor de tareas‘ y se usa fundamentalmente para realización de builds, su testeo y su despliegue.

Arquitectura y configuración

Para utilizar Ant es necesario primero tener instalado Java y después la distribución de Ant. Algo similar ocurre con Grunt para poder usarlo es requisito tener instalado node.js y el cliente de Grunt.

Tanto en Ant como en Grunt la configuración de la build del proyecto se hace a través de un archivo. Su nombre por defecto en ‘build.xml‘ en Ant y ‘Gruntfile.js‘ en Grunt

Tareas y objetivos

En esencia tanto en Ant como en Grunt se utilizan las tareas disponibles (‘tasks‘) para definir objetivos (‘target‘). Los objetivos contienen la configuración de nuestro proyecto utilizando estas tareas… ‘Copia estos ficheros‘, ‘borra los ficheros de este tipo‘, etc..

En Ant un target pueden depender de otros. Se ejecutarán los targets de los que depende antes que él y lo harán en el orden indicado. Esto permite crear un flujo de ejecución de tareas.

1
<project name="Ejemplo de build" default="ejecutar">
2
...
3
 <target name="ejecutar" depends="clean,crearDistro,crearWar"/>
4
...
5
</project>

En este caso ‘ejecutar‘ sería el target por defecto.

En Grunt se definen ‘alias‘ para el mismo resultado.

1
...
2
grunt.registerTask('default', ['clean', 'copy','uglify', 'concat','cssmin']);
3
..

Eso no significa que no puedas ejecutar targets individuales. Por ejemplo en Ant para lanzar el target clean sería, ejecutando en el directorio donde está el ‘build.xml

1
$ ant clean

o en Grunt, ejecutado en el directorio donde está el ‘Gruntfile.js

1
$ grunt clean

Variables externas

Tanto en Ant como en Grunt se pueden pasar variables al archivo de configuración desde línea de comandos, lo que resulta muy útil a la hora de configurar varios entornos del mismo proyecto en el Jenkins.

En Ant

1
$ ant −DdirEntorno=prepro

Usando así la variable en el buid.xml

1
<target name="clean">	
2
 <delete dir="${dirEntorno}"/>
3
</target>

En Grunt:

1
$ grunt −−dirEntorno=prepro

Y el Gruntfile.js

1
clean: {
2
 main: {
3
  src: ['<%= dirEntorno %>']
4
 }
5
}

… y en que se diferencian

Xml o Json/Javascript

Ant utiliza xml para definir la configuración. Esto hace que, sobre todo al principio, y con archivos de build complejos, que sea bastante rígido y engorroso.

Grunt en este aspecto utiliza json, un formato mucho más liviano. Además está embebido en un archivo javascript permitiendo utilizar este lenguaje con toda su potencia. Este aspecto le da mucho más flexibilidad que Ant. Aquí es donde se le notan los años a Ant y como muestra Gant,una alternativa en el mundo Groovy que ‘pasa’ del xml

Gestión de dependencias de las tareas

La filosofía de las dependencias de las tareas es completamente diferente. Ant ,de serie, trae diferentes tareas que ya se pueden usar. Esto no significa que se puedan utilizar otras tareas de terceros. Para esto se usa la tarea ‘typedef‘.

La gestión de dependencias de las librerías que son necesarias para ejecutar estar tareas es completamente ‘a mano’. No te queda otra que bajarte la librería he incluirla, o bien en tu distribución de ant (en el directorio ‘lib’) o bien dentro de tu home (en el directorio ‘.ant/lib‘)

En esto Grunt si que gana por goleada. Por defecto no viene con ninguna tarea predefinida, por lo que eres el que elige cual vas a utilizar, seleccionandola de su página de plugins. Probablemente existan varias posibilidades a la tarea que estás buscando. Después, para poder utilizarla, Grunt utiliza la potencia del gestor de paquetes de node.js, npm.

Por ejemplo, para instalar la tarea ‘uglify‘ que se utiliza para comprimir archivos js, se ejecuta el siguiente comando en el directorio donde este el Grutfile.js

1
$ npm install grunt−contrib−uglify −−save−dev

Esto incluye las dependencias en el ‘package.json‘ (Este fichero se crea al iniciar el proyecto ejecutando ‘npm init’)

Y para pode usar la tarea hay que añadir al Gruntfile.js:

1
...
2
grunt.loadNpmTasks('grunt−contrib−uglify');
3
...

Fácil y cómodo, aunque tampoco falto de problemas. Por ejemplo la tarea clean de repente dejo de funcionar en Windows, mientras que el Linux no había problema. El problema, una de las dependencias subió de versión… y dejo de funcionar. La solución fue añadir la dependencia a la versión que funcionaba directamente en el archivo ‘package.json‘. Espero tener tiempo para explicarlo mejor en otro post.

Epílogo, Conclusiones

Si eres de Back ,tienes algo de experiencia en Ant y quieres montar tu control de configuración para el Front que está basado en Javascript, trabajar con ‘Grunt’ te va a resultar muy familiar.

Son tecnologías diferentes, algunas tareas serán similares y otras más específicas  no encontrarás en Ant, pero la esencia es la misma, así que sin miedo.

Espero que os sirva.

M.E.