BLOG

Lunes, 16 Octubre 2017 09:37

Electron – Un framework para desarrollo de aplicaciones de escritorio multiplataforma (Primera Parte)

AnatolyFoto

  Para el artículo de hoy presentamos a Anatoly Pedemonte, Software Architect  en Trans Solutions Systems, quien  nos contará un poco sobre Electron: qué es, cómo funciona, algunos features favorables, ventajas y desventajas de  utilizarlo, etc. Luego nos enseñará paso a paso cómo construir una verdadera  aplicación  con Electron.

 Este blog estará dividido en dos partes: En la primera se verá la parte teórica de  Electron, mientras que en la   segunda veremos la parte práctica con la  construcción de una aplicación.

 

 

1 Electron

                                                             Referencia: https://electron.atom.io 

¿Qué es electron?

Anteriormente conocido como Atom Shell, es un framework basado en JavaScript, desarrollado y mantenido por la comunidad oficial que apoya el proyecto GitHub el cual nos permite desarrollar sistemas de escritorio multiplataforma (Cross Platform Desktop Apps), mediante el uso de tecnologías web (JavaScript, HTML y CSS). Es de código abierto y multiplataforma (funciona bajo Linux, Mac y Windows). Y es por eso que javascript, se convierte en un tema tan redundante entre los desarrolladores. Es que hay motivos de peso para centrarse en esta plataforma.

2 Electron

Ilustración 1 - Actualidad de descargas de Electron

¿Cómo funciona Electron?

Electron funciona bajo un subconjunto mínimo de librerías de varios frameworks como NodeJS, Chromiun y el engine V8 JavaScript, además proporciona acceso a APIs nativas enriquecidas mediante el motor de Chromium, el cual es controlado mediante JavaScript. Por lo que no podemos confundir que enlaza a librerías gráficas del sistema operativo, ya que su GUI se desarrolla mediante HTML, pero podemos aprovechar ciertas características de las librerías nativas mediante Chromium. Compañías como Microsoft, Facebook, Slack, Docker entre otras están utilizando este framework como su parte de su stack de desarrollo para aplicaciones cross platform.

Además, ofrece a los desarrolladores una serie de features tales como: reporte de fallos, actualizaciones automáticas, depuración y análisis sistemático del contenido de la fuente de datos, menús y notificaciones nativas, etc.

Parte de los beneficios de la comunidad que soporta Electron, es que nos ofrece una aplicación demo de cómo usar las API’s de Electron con ejemplos interesantes para iniciarte en el desarrollo de aplicaciones sobre framework y hoy tiene un amplio ecosistema de utilidades como aplicaciones complementarias para su uso.

Puedes explorar un poco más sobre estas utilidades y su ecosistema en:  https://electron.atom.io/userland/

3 Electron

Ilustración 2 - Vista de la app de libre descarga de Electron API Demos (https://github.com/electron/electron-api-demos/releases)

Electron, por defecto soporta Node.js v6 y la última versión stable de Chromium, por el cual podemos usar casi todas las características de ECMAScript 2016, pudiendo también usar para funciones como Async/Await o soportar JSX si usamos React.js o Angular. Por lo que también podemos hacer una aplicación integrando funcionalidades de React o Angular y  consumir servicios  REST API de backend en .Net y Java, como si fuera una aplicación web o conectarse a una base de datos, ya que internamente está desarrollado con tecnologías web, pero con la diferencia que este aprovecha las condiciones y poder que le brinda el sistema operativo como aplicación de escritorio con características superiores a una aplicación web, incluyendo la integridad y la seguridad.

Referencia : JSX - https://jsx.github.io/ 

Chromium:

  • Es parte del proyecto de buscador de código abierto de Google.
  • Proporciona administrador de ventanas con pestañas, o shell para la web.
  • Tener una interfaz de usuario minimalista.
  • Usa el V8 Engine como el motor de JavaScript.
  • Utiliza Blink como el motor de diseño.
  • Los módulos de contenido y las API de contenido de Chromiun son usados por Electron.

NodeJS:

  • Es un famoso runtime de JavaScript en el lado del servidor multiplataforma y de codigo abierto, que tiene librerías para aplicar programación asíncrona.
  • Utiliza el motor de JavaScript V8 Engine.
  • Le permite ejecutar JavaScript fuera del navegador.
  • Proporciona un shell interactivo (REPL: read-eval-print-loop) donde puede ejecutar el código JavaScript nativo y sin formato.
  • Utiliza un controlador de eventos (event-driven), bajo el modelo non-blocking I/O que lo hace liviano y eficiente.
  • Tiene un amplio ecosistema de paquetes Node.js, npm, más grande de bibliotecas de código abierto en el mundo.

V8 JavaScript Engine:

  • Un motor JavaScript de código abierto desarrollado por The Chromium Project.
  • Escrito en C ++ y JavaScript.
  • Implementa ECMAScript como se especifica en ECMA-262, 3ª edición.
  • Funciona en Windows XP o posterior, Mac OS X 10.5+ y sistemas Linux que utilizan procesadores IA-32, ARM o MIPS.
  • Compila JavaScript en native y machine codes.

Se debe dejar en claro que Electron utiliza páginas web como interfaz gráfica de usuario por lo que, salvando las distancias, se podría ver como un navegador Chrome (que internamente posee el motor de Chromium) controlado por javascript. Además, utiliza la arquitectura multi-proceso de Chromium, es decir, cada página en Electron se ejecuta en su propio proceso, lo que se conoce como proceso de representación o Renderer, que posteriormente explicaremos.

4 Electron

Ilustración 3 - Electron y sus componentes del cual deriva e interactúa.

5 Electron

Ilustración 4 - Chromiun es su principal componente que permite producir una aplicación web como una Desktop App Cross Browser

Algunos features favorables para optar por Electron

  • Desarrollo rápido, configuración y compilación análoga como cualquier otro framework con Angular.
  • Manejo de Temas y uso de componentes de terceros por ejemplo KendoUI.
  • Código compartido con posibilidad de ser compilado como un todo.
  • Interfaz de usuario personalizable, legando a ser front end o GUI de otro lenguaje, por ejemplo con apps de Python.
  • Despliegue y actualizaciones silenciosas y se puede integrar como cualquier software al SDLC con CI/CD.
  • Propiedades nativas para el User Experience (Native UX)
  • Crear aplicaciones de escritorio usando tecnologías web conocidas (Javascript/CoffeeScript/ES6, HTML 5, CSS 3) como librerías asociadas (jQuery, React, Bootstrap, etc.)
  • Desarrollar aplicaciones multiplataforma (Windows, Mac OS X y Linux) sin necesidad de generar parches para que éstas funcionen.
  • Libertad y homogeneidad en el diseño visual de la aplicación.
  • Integra ya una API para actualizaciones automáticas y variedad para hacer despliegues y distribuciones.
  • Menus nativos.
  • Reportes cuando la app no responde (appCrash).
  • Todo un ecosistema de herramientas para depuración y análisis de código y testing.
  • Desarrollar una misma aplicación core y usar los beneficios de Windows, Mac y Linux.
  • Tambien poder integrar a bases de datos relacionales o NoSQL, incluyendo a las javascript in-browser database como por ejemplo PouchDB o NeDB.

Referencias:

NeDB - https://github.com/louischatriot/nedb

PouchDB - https://pouchdb.com

Ventajas (Pros)

  • HTML + CSS + JavaScript
  •  
  • No necesita dependencias nativas de un SO, para hacer los deployment.
  • Se pueden crear interfaces de usuario mucho más elegantes, responsivas e interactivas con otros frameworks de javascript, tales como:
    • AngularJS
    • EmberJS
    • Backbone
    • Marionette
    • Marionettist (Backbone + Marionette)
    • Knockout
    • Y otros frameworks

Desventajas (Cons)

  • Depender del HTML + CSS + JavaScript
  • Principalmente el desarrollo principal se debe hacer con JavaScript
  • Para casos especiales interactuar con algunos módulos nativos en C/C++

Negocios que necesitan de los Cross Platform Desktops Apps

  • Aplicaciones que requieran ser Offline y Online solo para ciertas tareas.
  • Printers, Devices y otros tipos de hardware
  • On-Premises
  • Negocios relacionados a Logistics y Transportation
  • Gestión de Multi-Media Datatypes or Internal LOB (Large Objects)
  • Empresas de aplicaciones que se venden desde un App Store
  • Quienes desarrollan Kioskos
  • Desktop apps de Intranet
  • Streaming data y video
  • Aplicaciones que requieran implementar funcionalidad de Store&Forward
  • Negocios que requieran una aplicación que justifique no estar en línea.

Ideas de aplicaciones:

  • Aplicaciones desconectadas para data entry
  • Editores de texto
  • Time management
  • Media players
  • Email clients
  • Messaging y E-collaboration
  • Kioskos
  • Mapping y route planner
  • Video Streaming
  • Dashboards
  • Social media clients
  • Calendarios o Agendas
  • Bulk media editors
  • File management o backup
  • Generación y procesamiento de Documentos
  • Audio/video conferencia
  • Juegos o plataformas de multiplayers
  • Asistentes Personales
  • Clientes de motores de base de datos, etc.

Definición de Procesos como arquitectura interna en una aplicación Electron

Los módulos de API’s de Electron, principalmente es controlado mediante el engine de JavaScript creando dos tipos de procesos, el Proceso Main y el Proceso Renderer, más conocidos como Main Process y Renderer Process.

  • El primero es un proceso (main) de , que es el proceso principal y viene a ser nuestra aplicación en sí misma, este proceso tiene acceso a varias API de Electron, proceso principal que nos ayudan a comunicarnos con el SO y realizar distintas acciones o efectos.
  • El segundo (renderer) es un proceso de Chromium, con una diferencia, este Chromium, necesita tener Node.js incorporado para acceder a todos sus módulos, haciéndolo genérico en su uso y utilidad utilizando npm (esto nos permitiría usar React.js, Angular.js, Polymer, Express,  Socket.io, etc. para desarrollar nuestra UI o cualquier otra librería básicamente), por lo que desde nuestro renderer podemos usar módulos de comportamientos de ventanas, módulos para leer y escribir en el disco, o hacer peticiones a una base de datos directamente. Además de acceder a los módulos de Node.js y npm, Electron.js nos da acceso a las API’s en este proceso, igual que hace con el proceso main.

Comunicación entre procesos 

Electron tiene varias formas de comunicarse entre el proceso principal (main) y los procesos de representación (renderer). Como los módulos ipcRenderer e ipcMain pueden comunicarse y enviar mensajes hacia un módulo remoto, se comunican al estilo RPC mediante módulos de tipo IPC (Inter-Process Communication).

Entendamos que los módulos que se usan comúnmente desde las API’s de Electron son:

  • ipcRenderer: Renderer Process
  • ipcMain: Main Process
  • remote: Renderer Process

6 Electron

Ilustración 5 -  Procesos principales que gobierna Electron y como se comunican

¿Cómo trabajan los módulos IPC que usa Electron?

Electron proporciona un tipo de comunicación a través de módulos IPC (inter-process communication).

IPC permite suscribirse a mensajes en un canal y enviar mensajes a suscriptores de un canal. Un canal se usa para diferenciar entre receptores de mensajes y se representa mediante una referencia de tipo string (por ejemplo, "canal-1", "canal-2", etc).

El mensaje también puede contener una colección de datos. Al recibir un mensaje, el suscriptor puede reaccionar haciendo algún trabajo e incluso puede responder. El mayor beneficio de la mensajería es la separación de preocupaciones o responsabilidades, por lo que el proceso principal no tiene que saber qué renderers hay o cuál envió un mensaje.

7 Electron

Ilustración 6 - Descripción gráfica de la comunicación del tipo IPC y como se suscriben, envían y reciben  mensajes 

La representación de suscripción, envío y recepción de mensajes a través de los módulos ipcMain y ipcRenderer, aplicado desde código mediante un ejemplo básico: 

Diagramas conceptuales de cómo interactúan los componentes y los procesos

9 Electron

Ilustración 7 - Diagrama de arquitectura del IPC con los procesos y componentes

10 Electron

Ilustración 8 – Interacción Conceptual de Main Process y Renderer Process, donde nuestro main.js puede suscribirse a varios renderers.

11 Electron

Ilustración 9 - Los menus también comparten el comportamiento de Renderer dentro del esquema de procesos.

Los siguientes gráficos, nos ayuda a entender facilmente como se distribuyen los procesos Main y Render, con los principales archivos que debe tener como base una aplicación en Electron.

12 Electron  13 Electron

14 Electron

Ilustración 10 - Main.js representado como parte del Main Process  con los archivos html como ventanas dentro del contexto de Renderers. 

Se ha preparado una aplicación demostrativa implementando los procesos principales que usa Electron y que se detallará mas delante de este post.

Las API’s de Electron 

Electron tiene una completa variedad de API’s que para cada contexto de sus procesos puede interactuar como un conjunto de módulos de las API’s de Electron que permite sacarle provecho a cada sistema operativo, aquí un detalle de algunos módulos de las API por cada proceso.

15 Electron

                                                                             Referencia: La lista completa de las API’s - https://electron.atom.io/docs/api/

Principales herramientas y ecosistema en Electron

  • Electron, que permite instalar los binarios Electron desde el uso de la línea de comando usando npm.
  • electron-compile.
  • electron-packager, que permite desplegar y empaquetar aplicaciones electron.
  • electron-builder, herramienta para crear instaladores multiplataforma.
  • electron-debug
  • electron-reload
  • electron-updater
  • electron-mocha
  • Devtron, extensión oficial de DevTools. Proporciona funciones para depurar todos los componentes electrónicos.
  • Spectron, herramienta para test de aplicaciones Electron usando ChromeDriver.
  • Entre otras más de mucha importancia.

La lista completa de recursos desarrollado por  comunidad y que alimenta el ecosistema de Electron, como Tools, BoilerPlates, componentes, videos, etc, puedes visitar https://electron.atom.io/community/   y todos los recursos open-source de aplicaciones y dependencias para electron en  https://electron.atom.io/userland/.

16 Electron

Ilustración 11 – Tecnologías y Frameworks que forman parte del ecosistema de Electron

Inicio y primeros pasos para el desarrollo en Electron

Para utilizar Electron debemos tener instalado previamente NodeJS, integrado con un gestionador de dependencias como NPM o Yarnpkg para obtener los paquetes mediante el comando npm:

16.1 Electron

Desarrollando una aplicación “from scratch”

Por lo que debemos tener en cuenta las siguientes actividades, las cuales en resumen son:

  1. Instalamos requisitos previos necesarios.
  2. Creamos carpeta de proyecto
  3. Inicializamos nuestro package.json
  4. Creamos el index.js
  5. Creamos la vista (index.html)
  6. Como empaquetar aplicaciones
  7. “npm start” para poner a prueba nuestra aplicación

Para el desarrollo de nuestro proyecto debemos seguir como base la siguiente estructura de directorios:

electron 199

Para empezar a usar Electron lo primero que necesitamos es iniciar un proyecto con npm init e instalar la dependencia de desarrollo electron. Esta dependencia nos permite iniciar nuestra aplicación de Electron con el comando ‘electron .  ’.

Veamos cómo quedaría nuestro package.json luego de instalar todo:

 

Ahí tenemos nuestra dependencia de desarrollo instalada y el script start que inicia la aplicación, también definimos que el entry point de nuestra aplicación va a ser el archivo index.js ubicado en la carpeta app. Vamos entonces a crear este archivo y dentro vamos a colocar lo siguiente:


Como pueden ver en nuestro archivo main.js ejecutara el proceso principal de nuestra aplicación aquí podemos ejecutar el ciclo de vida de nuestra aplicación y observamos que hemos creado variables ‘app, BrowserWindow ‘como parte de Electron la cual contiene nuestro objeto de nuestro framework.

El objeto BrowserWindow se utiliza para agregar las diferentes pantallas de nuestra aplicación que será al final una ventana como la de nuestro explorador Chrome.

También necesitamos crear un HTML inicial, que permite cuando iniciemos Electron, ver una ventana en blanco con el mensaje: ‘Esta es mi primera app de Electron’.

Como un ejemplo también podemos incluir un poco de código de JavaScript en nuestro HTML como parte de nuestro objeto renderer y vamos hacer uso del módulo fs (directo en la ventana). Vamos a incluir una etiqueta script con el siguiente código:

19.1 Electron

En resumen lo que ordenamos en esta porción de código, es que si no hay ningún error vamos a ver todo el contenido del archivo package.json,  impreso en el HTML de nuestra aplicación. 

20.1 Electron

Al correr el comando para iniciar la aplicación, el resultado de nuestra primera aplicación será tal cual como se muestra en la imagen.

21 Electron

Ilustración 12 – Resultado de nuestro primera app en Electron.

Una ventaja de usar Electron, es que desde el mismo HTML invocando las API’s con ‘require’, referenciamos a dos módulos de Node.js para leer un archivo, gracias a que el proceso renderer que es un Chromium+Node.js, podemos combinar cualquier módulo que funcione en ambos, para hacer aplicaciones.

También te permite hacer empaquetados para distribuir la aplicación

Antes debemos de tener cuenta que para nuestras distribuciones los íconos para nuestras aplicaciones en sus diferentes tipos:

•icon.ico (Requerido para Windows)
•icon.png (Requerido para Linux)
•icon.icns (Requerido para Mac OS Darwin)

Para poder empaquetarla y distribuirla, tenemos que utilizar una herramienta llamada  ‘electron-packager’ el cual nos permite generar los .app, .exe o .deb para nuestra aplicación

Así que vamos a instalarlo como dependencia de desarrollo y luego vamos a crear en la sección script del archivo ‘package.json’ con la siguientes líneas, que indica los comandos que se referenciarán desde la línea de comandos ‘npm’ o ‘yarn’:

22.1 Electron

La llamada desde los comandos de línea sería:

23.1 Electron

Hay otra opción que es usar ‘electron-builder’, este incluye más funciones que electron-packager, pero también te trata de hacer seguir una forma específica de crear y organizar tu aplicación. Hay otras herramientas más específicas para crear instaladores como ‘electron-winstaller’ (https://github.com/electron/windows-installer) o ‘electron-installer-dmg.

Y finalmente para terminar esta sección…

Como verán las opciones para empezar a desarrollar con Electron es tan amplia e interesante, que podemos imaginar hacer aplicaciones vanguardistas para entornos de escritorio.

Pero aún no termino, el gran desafío de este post es hacer una aplicación que contenga las principales caracterisiticas de sus procesos en una verdadera aplicación de ejemplo que maneje mínimo 2 ventanas, esto se detallará posteriormente.

En un futuro si el tiempo me lo permite, continuaré con otros posts, acerca de cómo implementar aplicaciones Desktop CrossPlatform, con Angular, .Net Core  sobre la base de una aplicación hecha en Electron.