En este tutorial vamos a ver como la integración entre Angular 2 y Polymer facilita la creación de aplicaciones multiplataforma y multidispositivo empresariales.
Índice de contenidos
- 1. Entorno
- 2. Introducción
- 3. Nos ponemos la gorra de arquitectos y diseñadores
- 4. Nos ponemos la gorra de desarrolladores
- 5. Conclusiones
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
- Atom 1.7.3
- @angular 2.0.0-rc.1
- Polymer 1.4.0
2. Introducción
Cuando te planteas (o te plantean) hacer una aplicación del lado del cliente, que pueda aprovechar las ventajas de los web components, es muy fácil que actualmente valores dos tecnologías por encima del resto: Angular 2 y Polymer.
Si has leído algo sobre ellas te habrás dado cuenta de que las dos son de Google y que hay una guerra fraticida entre ellas por ver quien se queda con el pastel completo del desarrollo de aplicaciones del lado del cliente.
En mi opinión, es una guerra que las dos tienen completamente pérdida porque cada una es la mejor en su campo: Angular 2 como framework (o plataforma, como la quieren vender después de la última ng-conf) y Polymer como librería para crear componentes web reutilizables, también de forma rápida y sencilla.
Polymer está conceptualmente por encima de Angular 2, y es la tecnología que dentro de una empresa deberían utilizar los arquitectos y diseñadores para crear librerías de componentes que poder ofrecer a sus desarrolladores, para construir cualquier tipo de aplicación web. Estos roles deberían centrarse en aportar riqueza visual y reutilidad a los componentes por lo que una de las premisas fundamentales es que deben abstraerse del negocio, trabajando solo con estructuras de datos y aplicando patrones de diseño para favorecer la reutilización de los componentes, creando etiquetas HTML que los desarrolladores puedan utilizar fácilmente para aportar riqueza visual a las aplicaciones manteniendo un estilo corporativo único. Por contra, conceptualmente es mucho más costoso (no digo que no se pueda) crear una aplicación completa donde hay que intercomunicar todos los componentes y manejar conceptos de framework como el routing de una manera mucho menos clara y mantenible que con Angular 2.
Angular 2 como framework está mucho más orientado a desarrolladores que tienen que dar una respuesta casi inmediata a los requisitos de negocio. Con Angular 2 es muy rápido crear el prototipo de una aplicación pero no tiene ninguna característica que favorezca la reutilización de componentes y la riqueza visual de la aplicación. Por otro lado proporciona inyección de dependencias que facilita el testing general de la aplicación y maneja el routing, el data binding y las conexiones con servidores a través de HTTP de una manera mucho más sencilla que Polymer.
Entonces el caballo ganador es dejar que los desarrolladores creen las aplicaciones sin perder tiempo en el aspecto visual y centrándose en el aspecto funcional dando solución a los requisitos de negocio; mientras los arquitectos y diseñadores facilitan componentes reutilizables que permitan a los desarrolladores, simplemente con la utilización de ciertas etiquetas, dar el estilo visual que la empresa requiera.
Vamos a ver como podemos hacer esto en la práctica.
3. Nos ponemos la gorra de arquitectos y diseñadores
Como arquitectos y diseñadores solo tenemos que preocuparnos por la reutilización y el diseño visual, que no es poco. Así que tenemos que aprender a fondo el funcionamiento de Polymer.
Si recurrimos a la documentación oficial nos damos cuenta de que está completamente orientada a la creación de aplicaciones, incluso te facilitan una herramienta que te crea una aplicación de forma rápida, pero a poco que entras en ver como está configurada te das cuenta de que no entiendes ni la mitad de las cosas que hace.
En mi opinión esto es un error ya que lo que deberían facilitar es una herramienta orientada a la creación de librerías de componentes reutilizables; es por eso que me decidí a crear un generador de Yeoman con lo básico para la creación de una librería de componentes reutilizables con Polymer, que podéis instalar de esta forma:
$> npm install -g generator-polymer-lib $> mkdir nombre-empresa-lib && cd nombre-empresa-lib $> yo polymer-lib
Esto os va crear toda la configuración necesaria y un par de componentes de ejemplo, que podréis visualizar ejecutando:
$> npm run live
La estructuración del proyecto es muy sencilla, todos los componentes tanto propios como de Polymer que queramos compartir con nuestros desarrolladores están alojados en el fichero lib/lib.html y en el fichero index.html tendremos el banco de pruebas con la documentación de cada uno de los componentes. El proyecto está gestionado con Bower que es el gestor de dependencias que utiliza Polymer.
Ahora para poder compartir la librería con nuestros desarrolladores necesitamos hacerlo a través de un repositorio npm privado, yo aconsejo utilizar la última versión de Nexus OSS que nos permite tener rápidamente un repositorio de npm privado y corporativo; también tiene repositorios para Bower, NuGet e incluso Docker.
4. Nos ponemos la gorra de desarrolladores
Como desarrolladores nos gustaría poder centrarnos en la lógica de la aplicación encomendada y no tener que pasar horas moviendo arriba y abajo el CSS porque salvo honrosas excepciones un desarrollador no tiene mucho gusto estético.
Si vamos a la documentación oficial de Angular 2, vemos que existe ya una herramienta para la creación de aplicaciones, angular-cli , que a través de comandos nos permite ir creando la aplicación. La idea es buena pero a mi personalmente el hecho de que la hayan «copiado» del ember-cli y que tenga que utilizar BrocroliJS como automatizador de tareas teniendo otras soluciones ya probadas como Grunt, Gulp, Webpack o JSPM, me echa un poco hacia atrás a la hora de aconsejar su utilización.
Es por ello que he creado otro generador de Yeoman que te permite arrancar tu proyecto Angular 2 en pocos minutos con la ayuda de JSPM.
$> npm install -g generator-ng2 $> mkdir nombre-proyecto && cd nombre-proyecto $> yo ng2
Cuando finaliza el proceso de instalación tienes a tu disposición los siguientes comandos:
- npm run live: para arrancar la aplicación en el navegador que tengas configurado por defecto.
- npm run test: para ejecutar la batería de tests con Karma y obtener los informes de cobertura con Istanbul.
- npm run compile: para generar los ficheros transpilados necesarios para la ejecución de los tests y la corrección de errores en tiempo de compilación. Si usas Atom está tarea ya la realiza el editor, aunque a veces, sobre todo cuando se renombran ficheros, no viene mal ejecutarla para volver a generar «limpio» el contenido de la carpeta «build».
- npm run pro: para generar un único bundle.js preparado para poner en producción.
Ahora lo que queremos conseguir es poder integrar con la librería corporativa que se encuentra en un repositorio privado. Con JSPM es tan sencillo como ejecutar:
$> jspm install npm:nombre-empresa-lib
Nota: nos tenemos que asegurar de tener la referencia a ese repositorio privado correctamente configurada en el fichero ~/.npmrc
De esta forma ya tendremos la librería entre nuestras dependencias de proyecto, ahora para poder hacer uso de ella, vamos a referenciar el fichero lib.html dentro del archivo «bootstrap.ts», quedando de esta forma:
import 'nombre-empresa-lib/lib/lib.html!' import 'reflect-metadata' import 'es6-shim' ...
Te habrás percatado del signo de exclamación, esto le dice a JSPM que tiene que utilizar el plugin de HTML para poder realizar el import. Para poder hacer uso de este plugin, tenemos que instalarlo junto a la dependencia de vulcanize, que comprime todos los ficheros HTML importados en un solo llamado bundle.html:
$> jspm install html=github:Hypercubed/systemjs-plugin-html $> npm install vulcanize --save-dev
En este momento ya podemos aplicar cualquier elemento de nuestra librería de arquitectura en cualquier template de nuestra aplicación con Angular 2 e incluso en nuestro index.html (fuera del scope de la aplicación de Angular 2).
Ahora si volvemos a obtener el bundle de producción con el comando «npm run pro» veremos que ya no solo genera el bundle.js sino que también genera el bundle.html, los cuales tenemos que referenciar en el index.html de producción (el que se encuentra dentro de la carpeta «dist») junto con el polyfill de webcomponents y la librería de systemjs, quedando de esta forma:
Ahora ya podemos utilizar esta versión para crear una aplicación móvil híbrida con Cordova, o una aplicación de escritorio con Electron, o subirlo a cualquier servidor web, o crear un portlet de Liferay, o un contenido de WordPress, … lo que se requiera desde negocio.
5. Conclusiones
Como veis el binomio Angular 2 + Polymer nos permite llevar una estrategia empresarial adecuada, donde cada rol se dedica a lo suyo y las aplicaciones reflejan la imagen que la empresa quiere transmitir en cada momento.
Cualquier duda o sugerencia en la zona de comentarios.
Excelente, creo que es el camino natural, angular tendra que absorber en su interior a polymer, pero polymer debe mantener su autonomia, algo asi como lo que pasa con jQuery y angular 1 actualmente.
Hola Raúl, enhorabuena por el tutorial y la charla.
Quería hacerte una pregunta en relación a dónde estaría el límite entre lo que debe caer sobre el mundo Angular y lo que debe caer sobre el mundo Polymer. Coincido contigo en que todo lo que es Polymer será un componente mucho más reutilizable que un @Component de Angular, ya que es independiente del framework que utilices por debajo (Angular, React, Backbone…), y que si algún proyecto de los que se llevan a cabo en la empresa/organización necesita un framework distinto, no habría que reescribir dicho componente o pieza software.
Partiendo de la premisa de tu charla, Angular2 + Polymer, supongamos que queremos crear un componente «tnt-pwd-creator», compuesto por dos paper-input que controla la lógica de que la contraseña y la confirmación de la contraseña, coinciden. Además, mediante un flag que se le pasa como atributo, podrá mostrar la típica barrita que indica la fortaleza de la contraseña como información adicional al usuario.
Dicho componente podría ser utilizado en múltiples proyectos, pues (en un hipotético caso), digamos que la etiqueta ya tiene toda la lógica necesaria de todos los casos de uso. Con ese enfoque, la etiqueta debería proporcionar un two-way-databinding para que lo que se escribe en el input del webcomponent (polymer) sea pasado al padre (componente Angular) y recogido para poder trabajar con esas variables (posiblemente, enviarlo al servidor). ¿Debería quedar esa lógica dentro del webcomponente o residir en el componente de Angular? Si nos referimos a que los componentes sean sólo de representación visual, los inputs quedarían en Angular para tenerlos controlados mediante, digamos, un [(ngModel)], por lo que la definición del componente en polymer, no tendría sentido, y para reutilizar ese componente en otros proyectos ya no sería tan limpio como llevarse el .html o como añadirlo mediante npm.
Dicho esto, y disculpa si ha quedado un comentario bastante largo, ¿cuál es tu opinión? ¿Cómo abordarías este hipotético caso? He puesto este ejemplo porque es algo más complejo que el tnt-card.
Muchas gracias por tu tiempo.
Un saludo,
Creo que es posible la integración entre Polymer y Angular, pero tal vez termine pasando lo mismo que paso con jQuery y AngularJS, las cosas que hacías con jQuery también las podías hacer con AngularJS. Tal vez con Polymer pase lo mismo, las cosas que hoy se pueden hacer con Angular2 en un futuro también se puedan hacer con Polymer y terminen fusionándose hacia Polymer (Hoy mismo se pueden hacer componentes no visuales, por ejemplo iron-ajax).
Buenas Raúl, interesante integración de tecnologías. Llevo un par de meses aprendiendo Angular2 y ahora me ha surgido el utilizar Polymer. He encontrado tu repo en Github con la solución pero no soy capaz de lanzarla y ver el resultado por mí mismo. ¿Podías darme alguna indicación para arrancar la app?
Una duda más, ¿es posible utilizar los componentes Polymer sin crear una librería para importarlos? Llevo un par de días y no consigo nada
Gracias de antemano
[…] Integración de Angular con Polymer […]