¿Cómo y por qué migrar un proyecto Meteor a CoffeeScript?


Escribir un proyecto web en Meteor es divertido, pero existen tareas repetitivas que involucran código donde intervienen muchas llaves y declaración de funciones una detrás de otra.

Por ejemplo, las secciones que pueden programarse sobre una plantilla (un template) son las siguientes:

Template.Persona.onCreated(function(){
     // código para cuando se crea la plantilla
});

Template.Persona.onDestroyed(function(){
    // código para cuando se destruye la plantilla
});

Template.Persona.events({
  'click button' : function(){
      console.log("clicked");    
  },
  'click a' : function(){
    console.log('link clicked');
  }
});

Template.Persona.helpers({
  'personas' : function(){ 
    return Personas.find(); 
  },
  'persona'  : function() { 
    return Personas.findOne({_id : this._id }); 
  }
});

Observa que solo se creó el esqueleto de las secciones JavaScript de una plantilla, junto con dos eventos y dos helpers. Considero que el principal obstáculo aquí es que al crecer la cantidad de helpers y eventos, la legibilidad del código se hace más difícil por la notación en que son escritas.

CoffeeScript al rescate

En estos casos CoffeeScript brilla, pues su simple sintaxis permite que te enfoques en la lógica. Esta es la versión en CoffeeScript del código anterior:

Template.Persona.onCreated ->
  # código para cuando se crea la plantilla

Template.Persona.onDestroyed ->
  # código para cuando se destruye la plantilla

Template.Persona.events
  'click button' : ->
      console.log "clicked"    

  'click a' : ->
    console.log "link clicked"

Template.Persona.helpers
  'personas' : -> 
    return Personas.find() 

  'persona'  : -> 
    return Personas.findOne {_id : this._id }

Es muchísimo más legible de esta forma. Por supuesto, acá estoy asumiendo que conoces el CoffeeScript y sabes interpretar el significado de las flechas finas (->) , los espacios en las llamadas a funciones, la importancia de la indentación, la ausencia del punto y coma, llaves y paréntesis.

Migrando a CoffeeScript

A continuación te brindaré varios consejos para evitar algunos problemas que se puedan presentar a la hora de escribir un nuevo proyecto o migrar uno existente.

1. Cuándo utilizar this

En CofeeScript la palabra reservada this se puede abreviar con el símbolo @. Utiliza este símbolo para declarar objetos que quieres sean globales:

# fichero both/colecciones.coffee
@Personas = new Meteor.Collection 'personas'

# en otro fichero
todas = Personas.find().fetch()

Este objeto es global y fue creado por ti. Sin embargo, observa que para utilizar este objeto y paquetes de terceros como iron:router, u objetos del propio núcleo de Meteor, no puedes invocarlos con @.

Por tanto, ten como regla a seguir que: “tus objetos y funciones se declaran con el símbolo @ y se usan sin él”. El siguiente ejemplo muestra cómo configurar iron:router:

# client/router.coffee

Router.configure
  layout : 'Layout',
  notFoundTemplate : 'NotFound'

Router.map -> @route '/' , template: 'ListaPersonas'
Router.map -> @route '/new' , template: 'NuevaPersona'

Utiliza this en lugar de @ cuando lo uses como argumento en la llamada a una función o como objeto de retorno:

# No recomendado

crearComponente( @ )
return @

# Recomendado

crearComponente( this )
return this

2. Enviar Emails

Es probable que alguna vez tu aplicación necesite notificar a tus usuarios mediante correo. En ese caso deberás concatenar Strings con variables y sabes que JavaScript por esa parte no es muy amigable en su sintaxis:

Meteor.methods({
  enviarConfirmacion : function(){
    var token = getTheToken();
    var url   = getTheURL();
    var mensaje = "Hola, accede al siguiente enlace"
    + "para cambiar tu contraseña: " + url + "/" + token;

    var from = "mycyberacademy@gmail.com";
    var to   = "usuario@gmail.com";

    Email.send( from , to , mensaje );     
  }
});

Es muy fácil enviar emails con una sintaxis amigable desde CoffeeScript. Hay dos características de este lenguaje que debes conocer para realizar manipulación de cadenas de forma amigable:

  1. Interpolación de variables.
  2. Concatenación multilínea.

El primer punto significa que dentro de la propia cadena puedes incluir variables: "La variable person tiene el valor #{person}".

El segundo punto permite escribir la cadena en varias líneas sin concatenarla. El ejemplo anterior se expresa en CoffeeScript de la siguiente forma:

Meteor.methods
  enviarConfirmacion : ->
    token = getTheToken()
    url   = getTheURL()

    mensaje = """
       Hola, accede al siguiente enlace
       para cambiar tu contraseña: #{url}/#{token}
    """

    from  = "mycyberacademy@gmail.com";
    to    = "usuario@gmail.com";

    Email.send  from , to , mensaje

Las tres comillas permiten escribir múltiples renglones sin necesidad de hacer algún tipo de concatenación, mientras se interpolan las variables url y token. Un mensaje más largo se ve muy natural con esta sintaxis, manteniendo una legibilidad óptima.

3. Combinar JavaScript con CoffeeScript

Puedes tener un proyecto híbrido, con ficheros js y ficheros coffee. Lo recomendable es mantener la uniformidad, pero si necesitas mantener tu proyecto heterogéneo perfectamente lo puedes hacer.

Verificando la equivalencia en JavaScript

Usualmente sucederá algún error en tu código y querrás ver el código JavaScript resultante de la compilación desde CoffeeScript.

Para utilizar CoffeeScript en tu proyecto debes instalarlo con el comando meteor add coffeescript. Dicho paquete realiza la compilación en tiempo de ejecución, por lo que para ver el resultado, debes hacerlo desde el navegador:

Conclusiones

Sin dudas el duo Meteor + CoffeeScript se acerca al dream team del desarrollo web moderno.

Muchas características de EcmaScript 2015 están presentes en CoffeeScript hace años. Por tal motivo prefiero utilizar CoffeeScript en mis proyectos antes de ES2015 junto a un transpiler como Babel o Traceur.