El mundo de Angular Schematics

En el mundo de la programación la velocidad de desarrollo es un factor clave a la hora de afrontar un proyecto. La aplicación no solo debe cumplir con la funcionalidad y calidad requerida por el cliente, sino que debe estar lista en unos márgenes de tiempo ajustados.

Por la propia naturaleza del funcionamiento y diseño de estas aplicaciones, existen grupos de objetos, componentes y plantillas HTML (podríamos incluir hojas de estilos y clases de testing) que comparten una estructura común y que roban tiempo de desarrollo por la necesidad de crear y configurar la jerarquía de carpetas y ficheros necesarios para implementar la funcionalidad...

"Pues hago Copy&Paste una vez tenga el primer módulo creado... "

Esta es la solución a la que recurrimos en más de una ocasión. Sin embargo, no siempre nos supone un ahorro de tiempo (aunque puede ayudar), sino que a veces nos trae mas problemas, ya que tenemos que asegurarnos de cambiar nombres de archivos, carpetas, clases, objetos, etc.

En estos casos, tenemos que asegurarnos de que hemos importado los componentes correctamente y configurar las nuevas rutas para hacer esta nueva parte accesible. A continuación, debemos borrar el código correspondiente al módulo copiado y comenzar con el propio de ese nuevo módulo.

Por lo tanto, como vemos, este método también nos trae una carga de trabajo que no está relacionada con la funcionalidad solicitada, pero es necesaria para que todo funcione correctamente.

"Bueno... ya está bien de tanta crítica... ¿qué propones? ¡Queremos soluciones, no más problemas! "

Si has estado usando Angular en cualquiera de sus versiones, habrás utilizado alguna vez el comando para crear proyectos:

ng new my-project [+options]

E incluso puede que hayas usado los comandos para crear componentes, servicios y módulos que ofrece Angular, que crean archivos con un contenido básico listo para ser implementado:

ng generate component my-component [+options]

ng generate service my-service [+options]

ng generate module my-module [+options]

...

¿Y si te dijese que puedes crear tus propios comandos para generar tus propias plantillas y procesos que configuran todo por ti?

"¡MIENTES! ¡Copiar y pegar es la única y verdadera forma!"

Bien.

Para crear estos archivos propios vamos a hacer uso de Angular Schematics, un generador de código basado en plantillas y que forma parte del ecosistema de Angular.

El primer paso será crear nuestro proyecto de Schematics, y para ello vamos a instalar Angular Schematics de forma global en nuestro sistema:

npm install -g @angular-devkit/schematics-cli

Ahora podremos usar el comando "schematics" desde la consola del sistema para crear nuestro proyecto de esquemáticos. Navegamos desde la consola hasta la ruta donde almacenamos nuestros proyectos y, con la siguiente línea, se nos creará una base para nuestras plantillas:

schematics blank --name=my-schematics-project

Nos creará un proyecto 'Node' con las dependencias de Schematics y un esquemático con el nombre del proyecto.

 

En definitiva, que tendremos dos archivos, sin contar con el archivo de Testing ("index_spec.ts"):

1. Collection.json

En este archivo JSON declararemos todos los esquemáticos que posea este proyecto (dentro del apartado "schematics"), por ahora solo hay uno:

 

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
	"my-schematics-project": {
  	"description": "A blank schematic.",
  	"factory": "./my-schematics-project/index#mySchematicsProject"
	}
  }
}

 

Podemos observar que en el apartado "factory" nos apunta al método "mySchematicsProject" del archivo "index".

 

2. Index.ts

Aquí es donde ocurre (u ocurrirá, más bien...) la magia.

export function mySchematicsProject(_options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
	return tree;
  };
}

 

Esta es la función a la que se llamará cuando lancemos el comando correspondiente a este esquemático y será donde implementemos todo lo necesario para generar los archivos en el proyecto de destino.

Por el momento no realiza cambios: devuelve un objeto "Rule" creado a partir del "Tree" del proyecto desde el que lanzamos (que representa el árbol del proyecto desde el que lanzamos el esquemático) tal cual está.

Una prueba sencilla sería crear un archivo "hello.txt" con el contenido "world". Para ello, modificamos el código anterior para añadir el fichero al árbol del proyecto.

export function mySchematicsProject(_options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
	tree.create('hello.txt', 'world'); // tree.create('nombredelarchivo.extension', 'contenido');
    return tree;
  };
}

 

Compilamos el proyecto con "npm run build" y hacemos la prueba con "schematics .:my-schematics-project --debug=false*" 

*Por defecto Schematics no nos modificará el árbol del directorio puesto que se ejecuta en modo Debug. Para ver los archivos resultantes desactivamos este modo.

 

¡Nuestro archivo se ha creado y aparece en el proyecto!

Este ha sido un ejemplo sencillo para comprender el funcionamiento de Schematics. Sin embargo también se ofrece la posibilidad de copiar un conjunto de elementos a la vez

Un ejemplo práctico de la utilización de esta herramienta sería crear unas plantillas para el tratamiento de Login de usuario en la aplicación.

 

Angular Schematics permite copiar jerarquías enteras de componentes y objetos (modíficándolas mediante opciones que podemos especificar mediante la propia llamada de comandos), como los especificados dentro de la carpeta ‘files’ de la anterior imagen.

Se crearán una serie de elementos más comúnmente usados para este fin como pueden ser: el RouteGuard, un enumerado con los roles de usuario para facilitar la legibilidad del código, un servicio base para las llamadas necesarias a la API que trate con las credenciales de usuario, una clase para representar el modelo del usuario (nombre, apellidos, token, rol, etc.), el propio componente de Login (los archivos TS y HTML) y un módulo que lo declara, que se añade automáticamente a la sección 'import' en nuestro AppModule.

 

Una vez lanzado este proceso podemos empezar a trabajar en la funcionalidad de este módulo en los archivos creados. Este, en concreto, era solo un ejemplo de las posibilidades que Angular Schematics ofrece.

Si recordamos el método que se generaba en nuestro index.ts:

export function mySchematicsProject(_options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
	return tree;
  };
}

 

Vemos que recibe un parámetro llamado ‘_options’.

Si recordamos los comandos utilizados para crear componentes y proyectos de Angular como: ng generate component my-component [+options]; podemos ver que hay una forma de pasar opciones extra a nuestros propios generadores.

Por citar un ejemplo, de los muchos que pueden surgir, tenemos  el caso en que queremos crear un archivo con un nombre especificado en el momento de lanzar nuestro comando.

Para configurar las opciones que tendrá nuestro esquema, debemos añadir un atributo más en la declaración de nuestro comando en Collections.json:

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "my-schematics-project": {
      "description": "A blank schematic.",
      "factory": "./my-schematics-project/index#mySchematicsProject",
      "schema": "./my-schematics-project/schema.json"
    }
  }
}

 

En este archivo (schema.json) vamos a indicar las opciones que el usuario podrá introducir cuando lance el comando correspondiente a este esquema. El siguiente es un ejemplo simple en el que pedimos al usuario un nombre para el archivo a generar:

{
  "$schema": "http://json-schema.org/schema",
  "id": "Test",
  "title": "",
  "type": "object",
  "properties": {
	"name": {
  	"type": "string",
  	"x-prompt": "Insert a name for the file"
  }
}

 

Esto nos permitirá añadir la opción name que recibirá un String cuando lancemos nuestro comando o bien nos lanzará el texto especificado en x-prompt y esperará hasta que hayamos introducido el dato.

A continuación, os pongo un ejemplo real en el que creamos unos componentes personalizados para nuestros proyectos (creamos a la vez un componente para listar una entidad, otro para su formulario de creación/edición y uno extra para modo consulta):

 

En definitiva, Angular Schematics supone un empleo activo de tiempo y esfuerzo para establecer un número interesante y útil de esquemas que nos recompensará de forma pasiva al utilizarlos en nuestros desarrollos futuros, pudiendo centrarnos en la funcionalidad y minimizando el tiempo que empleamos en la configuración solicitada por el propio framework Angular.

 

¿Qué os ha parecido este generador de códigos basado en plantillas? ¿Lo veis práctico? ¡Déjanos tu opinión en los comentarios!

Posts relacionados

Ventajas y beneficios de usar Docker para desarrollo a nivel empresarial

Ventajas y beneficios de usar Docker para...

CCMA movilización medios comunicación - SDOS

SDOS, nuevo partner digital de la CCMA

Comentarios
¿Qué opinas? Escríbenos. Nos encantará leerte :)