Creando nuestra primera app de escritorio con HTML, JS y Electron

Las aplicaciones web se vuelven más y más poderosas año tras año, pero aún queda espacio para las aplicaciones de escritorio. Sí, esas que cuentan con un acceso completo al hardware del ordenador. Hoy en día es posible crear aplicaciones de escritorio utilizando el código HTML con el que ya, supongo que estaréis familiarizados, JS y Node.js. Después lo empaquetan en un archivo ejecutable y lo distribuyen para Windows, OSX y Linux.

Existen dos proyectos muy populares open source que hacen esto posible. Por un lado tenemos a NW.js, que lo cubriremos en un futuro artículo, y por el otro tenemos Electron, que es lo que te vamos a explicar en este artículo.

Empezando con Electron

Las apps desarrolladas con Electron son solo sitios web que se abren con el navegador web Chromium embebido. Además de las APIs de HTML5 que conocemos, estos sitios web pueden utilizar el conjunto completo de modulos de Node.js y los módulos especiales de Electron que te proporcionan acceso al sistema operativo del usuario.

Por el bien de este tutorial vamos a desarrollar una aplicación sencillita que recoja los artículos más recientes de programacion.net a través de nuestro feed RSS y los muestre en un carrusel. A juzgar por la estructura de archivos, nunca pensarías que se trata de una aplicación de escritorio y no de un sitio web sencillo.

Vamos a echar un vistazo a los archivos más interesantes y a cómo funcionan, en un minuto, pero primero, vamos a dar una vuelta con la aplicación.

Ejecutando la aplicación

Ya que las apps de Electron, son apps de Node.js, debes tener instalado npm. Una vez lo tengas, abre un nuevo terminal o cmd en el directorio con los archivos extraidos y ejecuta este comando:

npm install

Esto creará una carpeta node_modules que contenga todas las dependencias Node.js requeridas por la app para funcionar. A partir de ahora todo debería ir como la seda, en el mismo terminal de antes, introduce lo siguiente:

npm start

La app debería abrirse en su propia ventana. Probablemente hayas notado que iniciar la aplicación no es demasiado “amigable”. De todas maneras, este es el camino del desarrollador para ejecutar una app de Electron. Cuando se empaquetan para el público, se instalan como un programa normal y se como un programa normal, es decir, con doble clic.

Cómo se hace

A continuación, vamos a hablar de los archivos más esenciales de cualquier aplicación en Electron. Vamos a empezar con package.json, que posee diversa información sobre el proyecto, como la versión, dependencias de la NGP y otros ajustes importantes.

package.json

{
  "name": "electron-app",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "dependencies": {
    "pretty-bytes": "^2.0.1"
  },
  "devDependencies": {
    "electron-prebuilt": "^0.35.2"
  },
  "scripts": {
    "start": "electron main.js"
  },
  "author": "",
  "license": "ISC"
}

Si has trabajado con Node.js antes, ya sabes cómo funciona esto. Lo más importante a tener en cuenta es la propiedad scripts, donde hemos definido el comando npm start, lo que nos permite ejecutar la aplicación como lo hemos hecho antes. Cuando la llamamos, solicitamos a Electron la ejecución del archivo main.js. Este archivo JS contiene un pequeño script que abre la ventana de la aplicación, y define algunas opciones y controladores de eventos.

main.js

var app = require('app');  // Module to control application life.
var BrowserWindow = require('browser-window');  // Module to create native browser window.

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
var mainWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform != 'darwin') {
        app.quit();
    }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
    // Create the browser window.
    mainWindow = new BrowserWindow({width: 900, height: 600});

    // and load the index.html of the app.
    mainWindow.loadURL('file://' + __dirname + '/index.html');

    // Emitted when the window is closed.
    mainWindow.on('closed', function() {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null;
    });
});

Echa un vistazo a lo que hacemos en el método "ready". Primero definimos una ventana del navegador y establecemos su tamaño inicial. Entonces, cargamos el archivo index.html en ella, que funciona de manera similar a abrir un archivo HTML en el navegador.

Como verás, el archivo HTML en sí no es nada especial: un contenedor para el carrusel y un párrafo donde la CPU muestre las estadísticas de la memoria RAM.

index.html

<!DOCTYPE html>
<html>
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Experimento Electron</title>

    <link rel="stylesheet" href="./css/jquery.flipster.min.css">
    <link rel="stylesheet" href="./css/styles.css">

</head>
<body>

<div class="flipster">
    <ul>
    </ul>
</div>

<p class="stats"></p>

<!-->In Electron, this is the correct way to include jQuery<-->
<script>window.$ = window.jQuery = require('./js/jquery.min.js');</script>
<script src="./js/jquery.flipster.min.js"></script>
<script src="./js/script.js"></script>
</body>
</html>

El HTML también vincula con las hojas de estilo necesarias, con las librerías de JS y los scripts. Por último, aquí tienes el código JavaScript real de la aplicación. En ella se accede al RSS de programacion.net, busca los artículos recientes y los muestra. Sin más dilación, aquí tienes el código Javascript.

$(function(){

    // Display some statistics about this computer, using node's os module.

    var os = require('os');
    var prettyBytes = require('pretty-bytes');

    $('.stats').append('Number of cpu cores: <span>' + os.cpus().length + '</span>');
    $('.stats').append('Free memory: <span>' + prettyBytes(os.freemem())+ '</span>');

    // Electron's UI library. We will need it for later.

    var shell = require('shell');


    // Fetch the recent posts on programacion.net.

    var ul = $('.flipster ul');

    // The same-origin security policy doesn't apply to electron, so we can
    // send ajax request to other sites. Let's fetch programacion's rss feed:

    $.get('http://programacion.net/rss', function(response){

        var rss = $(response);

        // Find all articles in the RSS feed:

        rss.find('item').each(function(){
            var item = $(this);

            var content = item.find('encoded').html().split('</a></div>')[0]+'</a></div>';
            var urlRegex = /(http|ftp|https)://[w-_]+(.[w-_]+)+([w-.,@?^=%&amp;:/~+#]*[w-@?^=%&amp;/~+#])?/g;

            // Fetch the first image of the article.
            var imageSource = content.match(urlRegex)[1];


            // Create a li item for every article, and append it to the unordered list.

            var li = $('<li><img /><a target="_blank"></a></li>');

            li.find('a')
                .attr('href', item.find('link').text())
                .text(item.find("title").text());

            li.find('img').attr('src', imageSource);

            li.appendTo(ul);

        });

        // Initialize the flipster plugin.

        $('.flipster').flipster({
            style: 'carousel'
        });

        // When an article is clicked, open the page in the system default browser.
        // Otherwise it would open it in the electron window which is not what we want.

        $('.flipster').on('click', 'a', function (e) {

            e.preventDefault();

            // Open URL with default browser.

            shell.openExternal(e.target.href);

        });

    });

});

Una cosa que mola del código anterior es que, en un solo archivo utilizamos de forma simultánea:

  • Librerías de jQuery
  • Módulos nativos de Electron
  • Módulos de Node.js

Y con esto nuestra app estaría lista.

Fuente: tutorialzine.com

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP