Skip to content

Instantly share code, notes, and snippets.

@AngelMunoz
Created April 20, 2020 02:39
Show Gist options
  • Save AngelMunoz/691892924513a3e5ba5ce8cfc4867672 to your computer and use it in GitHub Desktop.
Save AngelMunoz/691892924513a3e5ba5ce8cfc4867672 to your computer and use it in GitHub Desktop.

Aurelia

Aurelia es un framework web que desde 2015 saco la version 1.0 y actualmente esta trabajando en la version 2.0, Aurelia esta escrito totalmente en typescript y ofrece a sus usuarios la posibilidad de usar typescript o usar javascript 2015+ a traves de Babel.

En el sitio oficial de Aurelia se pueden encontrar algunas de las razones principales de por que usar dicho framewok

  • Facil Aprendizaje
  • Alto Desempeño
  • Ecosistema Extenso
  • Bindings Reactivos
  • Testing Sencillo
  • Convenciones de programacion sencillas y eficientes
  • Rutas, Composicion y aumentos progresivos

Facil Aprendizaje

Aurelia se aleja en lo mayor posible de sintaxis extrañas que causan ruido visual para cualquier programador, el html usado en aurelia es 100% html, no es una imitacion de HTML que tiene que ser compilado, cada ViewModel (equivalente a lo que es el controlador en Angular) se define de la manera mas sencilla posible

class HomePage {
  message = "Hello, Home!"

  log(event, message) {
    console.log(event.target.value,message)
  }
}
<template>
  <h1>${message}</h1>
  <input
    placeholder="Change me"
    value.bind="message"
    keyup.delegate="log($event, message)" />
</template>

en las simples lineas de arriba, se pueden apreciar los conceptos basicos de la gran mayoria de los frameworks hoy en dia, one-way binding, two-way binding, reactivity y templating entre otros.

Si bien lo que se puede apreciar es un ejemplo sencillo, no dista mucho de lo que podria ser un componente altamente complejo ya que estos mismos conceptos son aplicables en cualquier momento y no es necesario una sintaxis extra o del "mundo real" cuando un componente ya es de calidad industrial.

Alto desempeño y Bindings Reactivos

Aurelia tiene un sistema reactivo (similar a los observadores) de alto desempeño, Aurelia no se pelea con la plataforma y utiliza la potencia del DOM que existe hoy en dia, no utiliza virtual DOM's que pueden ser eficientes pero que a final del dia incurren en una penalizacion en el desempeño final de la aplicacion

  • aurelia-dbmonster es un ejemplo (que sigue usando librerias beta, no ha sido actualizado) que sigue siendo relevante en el 2020
  • Real World Example es un ejemplo de aplicaciones en el mundo real digamos el todomvc del mundo real.

Ecosistema Extenso

Aurelia ofrece ciertos plugins que ofrecen gran funcionalidad

  • Http
  • Validacion
  • App State (version redux de aurelia)
  • Internacionalizacion
  • Dialogos
  • Animaciones
  • Virtualizacion

y es posible escribir un plugin propio en caso de necesitarlo. Ademas tambien cuenta con plugins para VSCode, cuenta con su propio CLI que facilitan la forma en la que uno trabaja con apliaciones de Aurelia

Testing Sencillo

Cada aplicacion de aurelia creada con el CLI permite al usuario elegir que Framework para testing usar, desde Karma + Jasmine o Jest, en el caso del testing E2E se puede usar Protractor o Cypress

El siguiente ejemplo define como probar un Custom Component

  import {StageComponent} from 'aurelia-testing';
  import {bootstrap} from 'aurelia-bootstrapper';
  
  describe('MyComponent', () => {
    let component;
  
    beforeEach(() => {
      component = StageComponent
        .withResources('my-component')
        .inView('<my-component first-name.bind="firstName"></my-component>')
        .boundTo({ firstName: 'Bob' });
    });
  
    it('should render first name', done => {
      component.create(bootstrap).then(() => {
        const nameElement = document.querySelector('.firstName');
        expect(nameElement.innerHTML).toBe('Bob');
        done();
      }).catch(e => { console.log(e.toString()) });
    });
  
    afterEach(() => {
      component.dispose();
    });
  });

El siguiente ejemplo define como hacer un test E2E

  describe('aurelia homepage', () => {
    beforeEach(() => {
      browser.get('http://www.aurelia.io');
    });
  
    it('should have proper header text set', () => {
      expect(element(by.tagName('h2')).getText()).toBe('EXPECTED HEADER');
    });
  
    it('should find an about section', () => {
      expect(element(by.id('about')).isPresent()).toBe(true);
    });
  });

Convenciones de programacion sencillas y eficientes

Aurelia define ciertas convenciones para facilitar el uso del framework, desde los nombres de los archivos HTML+Typescript para definir un componente hasta para determinar que archivo es un servicio y puede ser inyectable en algun componente

http://aurelia.io/docs/fundamentals/app-configuration-and-startup#bootstrapping-aurelia

Rutas, Composicion y aumentos progresivos

utilizar Routers en Aurelia es sumamente sencillo, tambien permite definir multiples ViewPorts e incluso definir Layouts en caso de que se quiera seguir un estilo MVC para definir la estructura del UI

<!-- app.html -->
 <template>
      <ul repeat.for="nav of router.navigation">
          <li class="${nav.isActive ? 'active' : ''}"><a href.bind="nav.href">${nav.title}</a></li>
      </ul>
      <router-view></router-view>
  </template>
// app.ts
import {RouterConfiguration, Router} from 'aurelia-router';
  
  export class App {
    router: Router;
  
    configureRouter(config: RouterConfiguration, router: Router): void {
      this.router = router;
      config.title = 'Aurelia';
      config.map([
        { route: ['', 'home'],       name: 'home',       moduleId: 'home/index' },
        { route: 'users',            name: 'users',      moduleId: 'users/index', nav: true, title: 'Users' },
        { route: 'users/:id/detail', name: 'userDetail', moduleId: 'users/detail' },
        { route: 'files/*path',      name: 'files',      moduleId: 'files/index', nav: 0,    title: 'Files', href:'#files' }
      ]);
    }
  }

Aurelia tambien hace uso de los estandares de HTML para permitir UI's bastante flexibles, por ejemplo es muy facil crear componentes re-utilizables con Proyeccion basada en Slots e incluso la habilidad de renderizar diferentes view models de forma dinamica usando Composicion, esto permite que por ejemplo se puedan usar dos ViewModel diferentes con la misma informacion

// Shared.ts
export interface RegistroEstatal {
  nombre: string;
  edad: number;
  correo: string;
}
export enum  TipoRegistro { 
  Solicitud = './solicitudes',
  Aprobacion = './aprobacion' 
}
// Solicitudes.ts
export class Solicitudes {
  registro: RegistroEstatal;
  // ... logica del registro en el view model de Solicitudes
}
// Aprobacion.ts
export class Aprobacion {
  registro: RegistroEstatal;
  // ... logica del registro en el view model de Solicitudes
}

// solicitud-o-registro.ts
export class SolicitudORegistro {

  composicion: TipoRegistro = TipoRegistro.Solicitud
  registro: RegistroEstatal;
  async activate() {
    this.registro = await this.getRegistro();
    if(this.user.rol == 'admin') {

    }
  }
}
<!-- solicitud-o-registro.html -->
<template>
  <!-- Otros elementos del UI que pueden ser re-utilizados -->
  <compose view-model.bind="composicion" model.bind="registro"></compose>
</template>

esto habilita escenarios muy poderosos donde se conoce que la informacion es la misma, pero el comportamiento es diferente y todo esto se puede colocar de manera progresiva, es decir se puede hacer algo tan complejo o tan sencillo como se desee Aurelia da la infraestructura necesaria.

En la siguiente version de Aurelia (TBD) se podran obserbar muchisimos cambios que pueden ayudar a la migracion de componentes de otros frameworks, por ejemplo...

Podrias Enseñarle a Aurelia como "Hablar" Vue

@attributePattern
export class ColonPrefixedBindAttributePattern {
  [':PART'](name, value, [target]) {
    return new AttrSyntax(name, value, target, 'bind');
  }
}

@attributePattern
export class AtPrefixedTriggerAttributePattern {
  ['@PART'](name, value, [target]) {
    return new AttrSyntax(name, value, target, 'trigger');
  }
}
<input :value="value">
<button @click="handleClick()">

o inclusive Angular 2+

@attributePattern
export class BananaInBoxAttributePattern {
  ['[(PART)]'](name, value, [target]) {
    return new AttrSyntax(name, value, target, 'two-way');
  }
}
<input [(value)]="value">

esto tambien podria habilitar escenarios donde proyectos con otras sintaxis del lenguaje puedan ser migradas facilmente (al menos el HTML) sin muchos cambios y de manera progresiva

Puede leerse en esta entrada de blog la ultima actualizacion sobre el desarrollo de Aurelia vNext http://aurelia.io/blog/2019/10/31/aurelia-vnext-2019-fall-update

Estas son algunas de las ventajas de Aurelia

Algunas de las desventajas de Aurelia pueden ser que su comunidad no es tan grande como los tres principales Angular, Vue, React y por un tiempo esto pudo ser un problema ya que las preguntas en stack overflow, reddit y similares eran escasas, Afortunadamente aunque la comunidad no sea tan grande Aurelia tiene un Foro de Discourse donde los usuarios son re-dirigidos para concentrar preguntas y respuestas de cualquier tema que pueda surgir en Aurelia por ejemplo Solicitudes de ayuda y tambien ofrece soporte pagado aun con estos detalles la gente usualmente prefiere ver a Angular por que tiene a google en la espalda para muchos es un detrimente bastante fuerte ya que Google es un nombre Grande.

Los Tamaños compilados de la aplicacion tienden a ser un poco grandes si no hay cuidado y no se usan bien los ES Modules (por ejemplo import * as MyLib from 'libreria-o-archivo' o import ABC from 'abc;')

y en general cualquier desventaja que tenga Angular, es potencialmente aplicable a Aurelia, sinceramente hay pocas razones por las cuales no se quisiera usar Aurelia mas que

  • Desconocer el framework
  • No tiene un "Big Name" detras de Aurelia
  • Comunidad relativamente pequeña
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment