Creación de un generador de Yeoman

2
9895

En este tutorial vamos a ver lo sencillo que es crear un generador de Yeoman para ajustarlo a las necesidades de nuestros proyectos, y evitar el temido «folio en blanco» y no volver a repetir una y otra vez la configuración inicial cada vez que queramos arrancar un nuevo proyecto JavaScript.

Índice de contenidos

1. Entorno

Este tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Mac Book Pro 15″ (2,3 Ghz Intel Core i7, 16 GB DDR3)
  • Sistema Operativo: Mac OS X El Capitan
  • NVM v0.29.0
  • NodeJS v5.1.0
  • npm 3.3.12
  • Atom 1.3.2
  • Yeoman 1.5.1

2. Introducción

La forma más rápida de crear proyectos en JavaScript es utilizando Yeoman que es la herramienta que nos permite crear un proyecto a partir de una plantilla, a los javeros esto les recordara a los arquetipos de Maven.

Para poder utilizarla lo único que tenemos que hacer es instalarla con npm

$> npm install -g yo

En Internet hay multitud de plantillas llamadas “generators”, un amplio listado lo podemos encontrar en: http://yeoman.io/generators/

Estos pueden ser instalados de la misma forma, por ejemplo:

$> npm install -g generator-ionic
$> npm install -g generator-ng2

Nota: es importante instalarlos con -g para que se haga de forma global, ya que no tenemos proyecto al que asociarlo.

De esta forma cuando queramos crear un proyecto usando una de estos generadores, solo tendremos que hacer dentro del directorio de nuestro proyecto.

$> yo nombre_generador_sin_generator
$> yo ionic
$> yo ng2

Y ya tendremos una semilla para empezar a programar.

3. Creación de un generador

Si no encontramos el generador adecuado siempre nos queda la opción de crear el nuestro propio, sigue estos pasos.

Lo primero será instalar el generador que nos permite hacer generadores. 😉

$> npm install -g generator-generator

Ahora creamos el directorio de nuestro generador y nos situamos dentro de él.

$> mkdir generator-tutorial
$> cd generator-tutorial

Invocamos al generador ejecutando:

$> yo generator

Y este nos hace una serie de preguntas:

  • Your generator name: por defecto, toma el nombre de la carpeta.
  • Description: damos una breve descripción de no más de una línea de lo que hace nuestro generador.
  • Project homepage url: si contamos ya con una url para el proyecto. Se suele poner la URL de github.
  • Author’s Name: el nombre que se quiera atribuir la creación del generador.
  • Author’s Email: el email del creador.
  • Author’s Homepage: si se quiere poner la URL de la página del autor.
  • Package keywords (comma to split): palabras significativas para clasificar el generador en los buscadores de npm.
  • Send coverage reports to coveralls: por si queremos enviar los informes para que estén disponibles.
  • GitHub username or organization: el usuario de github con el que queramos registrar el paquete.
  • Your website: por si quieres poner la URL a tu página.
  • Which license do you want to use?: permite seleccionar la licencia con la que queremos registrar el generador. Apache 2.0 es bastante adecuada, aunque dependerá del objetivo de cada uno.

Una vez aportada toda esta información se nos creará la siguiente estructura de carpetas:

img1-yeoman-creator

De esta estructura los archivos importantes son:

  • package.json: que va a contener toda la información del generador y que almacena parte de la información que hemos introducido en el asistente.
  • generators/app/index.js: es el fichero donde se detalla el proceso de instalación y copia de recursos necesarios.
  • generators/app/templates: va a contener los ficheros que queramos que tenga el proyecto que vamos a generar.

Para poder ir probando el desarrollo, npm nos permite enlazar este paquete en el registro global de nuestra máquina de forma que podremos crear un proyecto haciendo uso de este generador.

$> npm link

Ahora creamos el proyecto haciendo uso del generador, simplemente, creamos un directorio para nuestro proyecto dentro de él ejecutamos:

$> yo tutorial

Lo primero que llama la atención es la presentación y la pregunta “Would you like to enable this option? (Y/n)” que es un prompt de ejemplo que eliminaremos más tarde.

img2-yeoman-creator

Contestamos a la pregunta y nos va a crear la estructura de ficheros que tuviésemos dentro de la carpeta “templates”.

Ahora es cuestión de adaptar el contenido de la carpeta “templates” a nuestras necesidades. Para ello, vamos creando o copiamos de otros proyectos los ficheros deseados, como package.json, gulpfile.js, index.html, y directorios como app, test, …

Para este ejemplo, vamos a copiar un fichero package.json, junto con un index.html y un directorio app con el contenido del proyecto de ejemplo.

Pero no basta solo con copiarlos dentro del directorio “templates” tenemos que indicar explícitamente que queremos que ese fichero sea parte de la salida del generador.

Para ello, editamos el fichero generators/app/index.js que tendrá un contenido parecido a este:

'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');

module.exports = yeoman.generators.Base.extend({
  prompting: function () {
    var done = this.async();

    // Have Yeoman greet the user.
    this.log(yosay(
      'Welcome to the brilliant ' + chalk.red('generator-tutorial') + ' generator!'
    ));

    var prompts = [{
      type: 'confirm',
      name: 'someOption',
      message: 'Would you like to enable this option?',
      default: true
    }];

    this.prompt(prompts, function (props) {
      this.props = props;
      // To access props later use this.props.someOption;

      done();
    }.bind(this));
  },

  writing: function () {
    this.fs.copy(
      this.templatePath('dummyfile.txt'),
      this.destinationPath('dummyfile.txt')
    );
  },

  install: function () {
    this.installDependencies();
  }
});

En este fichero vamos a realizar una serie de modificaciones: la primera de ellas será eliminar el prompt que viene por defecto. Para ello sustituimos todo este bloque:

var prompts = [{
      type: 'confirm',
      name: 'someOption',
      message: 'Would you like to enable this option?',
      default: true
    }];

    this.prompt(prompts, function (props) {
      this.props = props;
      // To access props later use this.props.someOption;

      done();
    }.bind(this));

Por:

done();

La siguiente modificación será indicar los ficheros que van a formar parte de la salida del generador. Esto se hace dentro de la función “writing”, quedando de esta forma:

writing: function () {
    this.fs.copy(
      this.templatePath('package.json'),
      this.destinationPath('package.json')
    );
    this.fs.copy(
      this.templatePath('index.html'),
      this.destinationPath('index.html')
    );
    this.directory(
      this.templatePath('test'),
      this.destinationPath('test')
    );
  },

Tanto en “copy” como en “directory” especificamos el origen en el template y donde lo queremos situar en la salida.

Solo hay que tener especial cuidado con el fichero .gitignore, ya que node lo renombra a .npmignore (no me preguntéis por qué) y a la hora de crear el proyecto lógicamente no lo encuentra. Para solucionarlo hay que renombrar el fichero del template a _gitignore, por ejemplo, y especificar este nombre en el templatePath y poner .gitignore en destinationPath, de esta forma:

this.fs.copy(
      this.templatePath('_gitignore'),
      this.destinationPath('.gitignore')
    );

La función “install” es la encargada instalar las dependencias que vaya a necesitar nuestro proyecto:

install: function () {
    this.npmInstall(['tsd'], { 'global': true });
    this.npmInstall();
    this.runInstall(‘bower’');
  }

La primera sentencia sería para instalar cualquier dependencia de forma global, la segunda sería para ejecutar un “npm install” y la tercera se utiliza para ejecutar el comando “install” de bower, jspm, o lo que necesitemos.

Ahora para probar los cambios simplemente vamos al directorio de nuestro proyecto de prueba, borramos su contenido y volvemos a ejecutar:

$> yo tutorial

Y vemos como ahora el proyecto ha tomado la estructura que le hayamos indicado en el generador.

4. Publicación del generador

Una vez estemos contentos con nuestro generador, el siguiente paso será publicarlo, en el repositorio público de npm o en cualquiera que tengamos privado.

Este paso no difiere en nada de publicar cualquier otro paquete en el registro de npm público por lo que dentro del directorio de nuestro generador ejecutamos:

$> npm publish

Si es la primera vez que publicamos en npm, nos dará un error informando que primero tenemos que ejecutar el comando:

$> npm adduser

En caso de no tener cuenta en npm, primero vamos a la página https://www.npmjs.com/ y la creamos. Al ejecutar el comando, nos preguntará:

  • Username: nuestro usuario de npm
  • Password: nuestra password de npm
  • Email: (This is public): el email que queremos que se muestre

A continuación volvemos a la lanzar el comando:

$> npm publish

El registro se hará efectivo pasados unos minutos y cualquiera podrá instalar nuestro generador para poder ser utilizado mediante el comando:

$> npm install -g generator-tutorial

Si queremos eliminar la publicación del paquete solo tendremos que ejecutar desde dentro del directorio del generador:

$> npm unpublish --force

Nota: No es obligatorio pero si muy aconsejable tener un repositorio en GitHub asociado con el proyecto o el generador que hayamos subido a NPM

5. Conclusiones

Pues ya veis que crear nuestro propio generador de Yeoman aporta muchas ventajas y no es nada complicado, todo va a depender de lo especifico que lo queramos hacer.

Cualquier duda o sugerencia en la zona de comentarios.

Saludos.

2 COMENTARIOS

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad