Go es un lenguaje extraordinario que se utiliza comúnmente para interfaces de programación de aplicaciones (API por sus siglas en inglés) y/o bibliotecas. A la hora de crear interfaces gráficas, por lo general se utiliza un servidor web integrado. Sin embargo, existe otro enfoque que se está volviendo cada vez más popular. Wails es una tecnología que nos permite envolver código Go junto con frontend web en un único binario, simplificando las cosas.
El propósito de este artículo es familiarizarnos con Wails, brindando un ejemplo simple que nos permitirá visualizar el estatus de nuestro CPU de forma gráfica. Con este ejemplo lograremos una mejor comprensión de los conceptos básicos y obtendremos una nueva herramienta para cuando necesitemos construir algo similar.
¿Qué es Wails?
Wails es un framework que nos permite escribir aplicaciones de escritorio utilizando Go. La diferencia entre Wails y otras herramientas es que expone el código Go al frontend como funciones que devuelven promesas. Wails logra hacer esto por medio de un mecanismo de ligadura, el cual explicaremos más adelante.
El código front end se puede desarrollar utilizando cualquier framework de Javascript, como por ejemplo Angular, React, Vue.js y Vuetify.
Wails cuenta con la capacidad de envolver código Go así como frontend web en un único binario. La interfaz de línea de comandos de Wails hace que este proceso sea más fácil ya que se encarga de la creación, compilación y empaquetamiento de proyectos.
¿Cómo interactúa el código Go con el framework de Javascript?
La interacción entre el código Go y Javascript sucede a través de la comunicación entre procesos (IPC por sus siglas en inglés). Funciona a lo largo de Java runtime y Go runtime. Ambos proveen una interfaz simple que alivia la carga de lidiar con el mecanismo IPC directamente. El desarrollador puede interactuar con los componentes de Ligaduras y Eventos.
https://wails.app/about/concepts/
Ligaduras
La aplicación de Wails brinda un método único que expone el código Go al frontend. Se puede ligar una función o un ‘struct’. Al iniciar, Wails analizará las funciones ligadas y brindará una función equivalente en Javascript. Esto permitirá que el código Go pueda ser llamado desde Javascript.
El desarrollador solamente necesita llamar la función en Javascript y recibirá una promesa de vuelta. Si la solicitud de llamado del código Go se realiza exitosamente, el resultado pasará a la función de resolución. Si se da un error, entonces pasará a la función de rechazo.
Eventos
Wails posee un sistema unificado de eventos similar al sistema de eventos nativo de Javascript. Cada evento enviado por Go o Javascript es captado en ambos lados. Los datos pueden transmitirse sin problema.
Wails: instalación
Prerrequisitos
- Go v.1.12 o superior.
Nuestro ~/go/bin directory debe estar incluido en la variable de entorno PATH. También debemos asegurar que los módulos Go estén habilitados con:
echo “export GO111MODULE=on” >> ~/.bashrc
npm
gcc + libraries (xcode-select --install)
Construyamos una aplicación
Construiremos una aplicación de escritorio utilizando React y Go. Es una app simple para mostrar el uso de CPU de una máquina en tiempo real.
Cómo crear un proyecto
Comando:
wails init
Ingresamos el nombre del proyecto y escogemos el framework de Javascript que deseamos utilizar.
Para este ejemplo utilizaremos React. Este generará la siguiente estructura y los siguientes archivos para el proyecto:
Si queremos ejecutar el código que acabamos de generar:
- Ejecutar desde el React front end:
~/Documents/GoCode/wails/cpustats-react/frontend:$ npm start
- Ejecutar desde el backend:
~/Documents/GoCode/wails/cpustats-react:$ wails serve
La aplicación correrá en un navegador web: http://localhost:3000/. Veremos cómo se construye más adelante. Para propósitos de prueba y de eliminación de errores, podemos escribir código y revisarlo en el navegador.
Ahora, ¿cómo comenzamos a obtener los beneficios de utilizar Wails para nuestro proyecto?
Métodos de ligadura Go
Para ligar un método Go para utilizarlo en Javascript, éste se debe de declarar de la siguiente forma:
Observemos el método llamado ‘basic’. Debemos utilizar el método wails.CreateApp con la configuración deseada y luego debemos utilizar el método Bind() para exponerlo al frontend.
Ahora, para llamar este método en Javascript debemos utilizar window.backend.methodName. Notemos que esta es una promesa también. Observemos window.backend.basic() en el siguiente ejemplo:
Ligando structs
Supongamos que tenemos un struct creado en Go con el siguiente método: GetCPUUsage. Este método utiliza la biblioteca gopsutil para obtener el porcentaje de CPU de la máquina.
Para llamar este método struct en Javascript, debemos utilizar window.backend.StructName.methodName. En el ejemplo podemos ver cómo se llama el método struct: window.backend.Stats.GetCPUUsage(). En este caso, solamente vamos a imprimir el resultado en la consola.
Ligando eventos
Para ligar un evento utilizaremos WailsInit. Este método lo declararemos en el código Go. Observemos cómo declaramos un evento llamado cpu_usage. Este evento llamará al método GetCPUUsage cada segundo:
Para detectar el evento en Javascript utilizaremos Wails.Events.On, capturando el evento creado en Go (cpu_usage en este caso).
Para poder visualizar el uso de la CPU gráficamente y con una barra radial, utilizamos gráficos React. Para declararlos, utilizamos la biblioteca react-apexcharts.
Construyendo el proyecto
Utilizamos el comando wails build para construir el proyecto.
Esto creará nuestro archivo ejecutable: cpustats-react.
Además, podemos empaquetar la app utilizando wails build -p.
Esto generará un archivo .app y, en Mac, se verá así:
La imagen de la app también se puede modificar, cambiando la imagen appicon.png.
Al correr, la aplicación de escritorio se visualizará como la siguiente imagen. El uso de la CPU se actualizará cada segundo en la pantalla para reflejar el porcentaje correspondiente.
Referencias
- Página oficial Wails app https://wails.app/
- Go CPU package https://godoc.org/github.com/shirou/gopsutil/cpu
- Biblioteca React charts https://apexcharts.com/docs/react-charts/
Puntos ClaveLuego del ejemplo anterior, podemos concluir:
|