Aplicación de escritorio con JavaScript, HTML, CSS y el viejo confiable Electron

Camilo Herrera
winkhostingla
Published in
12 min readAug 31, 2023
  • Escribes software para la web y te pidieron una aplicación de escritorio?
  • Intentaste aprender lenguajes específicos para crear aplicaciones de escritorio y fallaste?
  • Notaste que vas a dejar de dormir y perderás tiempo de calidad con tu familia y/o mascota tratando de crear aplicaciones de escritorio?

Aprende de nuestra querida amiga y sus sabias palabras:

Y entremos juntos al mundo mágico de Electron framework para crear aplicaciones con lenguajes orientados a web.

Electron, qué es?

Electron es un framework y un conjunto de herramientas que te permiten ser un desarrollador de software perezoso que no quiere aprender…, corrijo, te permite usar HTML, CSS y JavaScript para crear aplicaciones de escritorio, esto lo logra embebiendo nodejs y chromium en un solo archivo ejecutable.

Impresionante verdad?, Electron es un proyecto que lleva años operando y es muy estable, con los años se han creado otras alternativas, pero estoy viejo y cansado y no voy a cambiarlo. A continuación algunas alternativas por si tienes curiosidad y estás pensando en uso de recursos como RAM o espacio en disco (Electron no es conocido por ser el mejor en esto) ó si quieres publicar tu aplicación en la App Store de cierta marca que usa una manzana:

Preparando nuestro entorno de desarrollo

Importante: Vamos a dejar algo claro antes de continuar, yo uso Windows, debido a esto, la guía estará centrada en este sistema operativo. Si usas uno diferente recomiendo consultar los pasos específicos o equivalentes para el que utilices.

Vamos a empezar por crear un directorio en algún lugar de nuestro PC en el que guardaremos los archivos de nuestro proyecto, en mi caso será (recuerda que es según tu configuración y preferencia):

D:\electron

A continuación instalaremos dos requisitos para usar Electron, son Node.js y npm.

Node.js+npm puedes descargarlo haciendo clic aquí y sigue las instrucciones de instalación al ejecutar el archivo.

El instalador ya incluye npm, no tienes que seguir pasos adicionales para instalarlo, a continuación inicia una consola de comandos y ejecuta las siguientes instrucciones para determinar si los requisitos están activos:

PS C:\Users\xxxxx>node -v
v18.16.0

PS C:\Users\xxxxx>npm -v
9.5.1

Si todo sale bien, será mostrada la versión de Node.js y npm instaladas en tu PC, de lo contrario te recomiendo realizar nuevamente el proceso o determinar si se presentó un error durante la instalación (o hay alguna restricción en tu equipo).

Para los que fueron exitosos en este paso, sigan conmigo y no se queden muy atrás.

Ahora, teniendo todo listo, vamos iniciar nuestro proyecto e instalar las herramientas de Electron en él.

Vamos a abrir una ventana de comandos en Windows (Terminal de powershell si somos más precisos), ingresamos D:\electron y creamos un nuevo directorio para nuestro proyecto específico así:

PS C:\Users\xx> cd D:\electron\
PS D:\electron> mkdir testapp
PS D:\electron> ls
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 30/08/2023 2:30 p. m. testapp

PS D:\electron> cd .\testapp\
PS D:\electron\testapp>

Dentro del nuevo directorio testapp creamos la estructura inicial de nuestra aplicación con el siguiente comando:

PS D:\electron\testapp> npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (testapp) TestApp
Sorry, name can no longer contain capital letters.
package name: (testapp)
version: (1.0.0)
description: My Electron Test App
entry point: (index.js)
test command:
git repository:
keywords:
author: Camilo Herrera
license: (ISC)
About to write to D:\electron\testapp\package.json:

{
"name": "testapp",
"version": "1.0.0",
"description": "My Electron Test App",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Camilo Herrera",
"license": "ISC"
}


Is this OK? (yes) yes

Durante el proceso serán solicitados los datos básicos de tu aplicación, puedes dejar los valores por defecto para la mayoría, pero la descripción y el autor son necesarios.

Ahora estamos listos para incluir las funcionalidades de Electron, dentro del directorio ejecuta el siguiente comando:

PS D:\electron\testapp> npm install --save-dev electron

Para ejecutar la aplicación usando Electron, es necesario un paso adicional. En el directorio fue creado un archivo con el nombre package.json, abre el archivo en un editor de texto y agrega una entrada en “scripts” con el valor “start”:”electron .” así:

{
"name": "testapp",
"version": "1.0.0",
"description": "My Electron Test App",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"author": "Camilo Herrera",
"license": "ISC",
"devDependencies": {
"electron": "^26.1.0"
}
}

No olvides la coma al final de la línea inmediatamente anterior. Guarda el contenido del archivo para finalizar.

Creando nuestra aplicación

Hasta este punto tu configuración básica está lista, ahora es necesario crear los archivos para mostrar la ventana principal de tu aplicación, para esto vamos a crear dos:

  • index.js
  • index.html

index.js es el punto de entrada de tu aplicación, tal como se indica en el archivo package.json

El contenido del archivo a continuación:

index.js

//Esta es la forma de incluír módulos con Node.js, en este caso el módulo 
//de Electron. Puedes consultar más sobre importación de módulos buscando
//información sobre CommonJS en internet
const { app, BrowserWindow } = require('electron')

//Creamos una ventana, aquí puedes fijar el tamaño inicial.
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
//El archivo que será cargado, vamos a crearlo en el siguiente paso.
win.loadFile('index.html')
}

//Evento de inicio de la aplicación, una vez esté "Ready", crea la ventana.
app.whenReady().then(() => {
createWindow()
})

Como paso adicional, vamos a agregar mi querida librería de CSS bulma, puedes descargarla de su sitio oficial bulma.io y guarda la carpeta bulma (dentro del .zip descargado) en el directorio de tu aplicación testapp, quedará así:

D:\electron
\testapp
\bulma
- index.html
- index.js
- package.json
- package-lock.json
\node_modules

Ahora nuestro archivo index.html, este contiene la estructura de la información a mostrar, tal como un sitio web… pero en tu aplicación de escritorio, entiendes el concepto?, es fácil.

You smart Electron!

index.html

<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<!-- El CSP es un PITA (si sabes a lo que me refiero ;))
le quitamos las restricciones con fines educativos,
no lo hagas en casa!-->
<meta http-equiv="Content-Security-Policy" content="">
<!-- incluimos bulma css -->
<link rel="stylesheet" href="bulma/css/bulma.min.css">
<title>My Test App</title>
<script>
window.addEventListener('load', (event) => {
document.querySelector(".hello").textContent = "Hello from Electron with bulma css!";
});
</script>
</head>

<body>
<section class="section">
<div class="container">
<div class="notification is-warning has-text-centered hello">

</div>
</div>
</section>
</body>

</html>

Este código html carga la librería css de bulma y crea una notificación con un mensaje que es fijado al finalizar el proceso de carga del DOM.

Desde aquí también puedes empezar a modificar o agregar secciones, puedes navegar de forma relativa entre archivos .html o usar librerías JavaScript tal como en un sitio web con tags script así:

<script defer src="/ruta relativa a mi archivo .js"></script>

Ahora puedes iniciar la aplicación por primera vez, desde la misma consola de comandos ejecuta la siguiente instrucción:

PS D:\electron\testapp> npm start

El resultado será algo como esto:

Mi primera aplicación con Electron

Si no quieres mostrar el menú por defecto de la ventana de Windows (nadie quiere eso en producción, para depuración puede ser útil ya que permite mostrar las herramientas de desarrollador dentro de la misma ventana.), puedes desactivarla editando tu archivo index.js y agregando la siguiente línea así:

win.setMenuBarVisibility(false)

index.js sin barra de menú

//Esta es la forma de incluír módulos con Node.js, en este caso el módulo de Electron
//puedes consultarlo buscando información sobre CommonJS en internet
const { app, BrowserWindow } = require('electron')

//Creamos una ventana, aquí puedes fijar el tamaño inicial.
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})

//Desactivamos el menú por defecto de la ventana de windows.
win.setMenuBarVisibility(false)
//El archivo que será cargado, vamos a crearlo en el siguiente paso.
win.loadFile('index.html')
}

//Evento de inicio de la aplicación, una vez esté "Ready", crea la ventana.
app.whenReady().then(() => {
createWindow()
})

Generando un ejecutable

Ahora vamos a compilar la aplicación en un ejecutable y a fijarle un icono.

Crea o descarga un icono de Windows (formato .ico) y guárdalo en un directorio con un nombre apropiado dentro de testapp, por ejemplo llamaremos el directorio icons, la estructura de directorios quedará así:

D:\electron
\testapp
\icons
- app.ico
\bulma
\node_modules
- index.html
- index.js
- package.json
- package-lock.json

A continuación vamos al archivo index.js y agregamos la ruta del icono así:

icon: 'icons/app.ico'

index.js con icono

//Esta es la forma de incluír módulos con Node.js, en este caso el módulo de Electron
//puedes consultarlo buscando información sobre CommonJS en internet
const { app, BrowserWindow } = require('electron')

//Creamos una ventana, aquí puedes fijar el tamaño inicial.
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
icon: 'icons/app.ico'
})

//Desactivamos el menú por defecto de la ventana de windows.
win.setMenuBarVisibility(false)
//El archivo que será cargado, vamos a crearlo en el siguiente paso.
win.loadFile('index.html')
}

//Evento de inicio de la aplicación, una vez esté "Ready", crea la ventana.
app.whenReady().then(() => {
createWindow()
})

Ahora ejecuta la aplicación, el icono debe ser mostrado en la barra de tareas y en la parte superior izquierda de la ventana.

Para empaquetar la aplicación y generar un ejecutable tendremos que instalar Electron Forge esta es la solución más común para realizar este proceso.

Dentro del directorio testapp ejecuta los siguientes comandos:

PS D:\electron\testapp> npm install --save-dev @electron-forge/cli
PS D:\electron\testapp> npx electron-forge import

Será mostrado el resultado de los comandos y un mensaje final de agradecimiento por usar Electron Forge.

Ejecuta de nuevo la aplicación con el comando inicial, notarás que ahora quien se encarga del proceso es Electron Forge y no Electron directamente, el proceso tomará unos segundos más pero el resultado será el mismo.

Para crear un ejecutable que pueda ser distribuido, ejecuta el siguiente comando en la misma consola:

PS D:\electron\testapp> npm run make

Me parece importante mostrar el resultado del comando en la consola, deberías ver algo como esto:

> testapp@1.0.0 make
> electron-forge make

✔ Checking your system
✔ Loading configuration
✔ Resolving make targets
› Making for the following targets: squirrel
✔ Running package command
✔ Preparing to package application
✔ Running packaging hooks
✔ Running generateAssets hook
✔ Running prePackage hook
✔ Packaging application
✔ Packaging for x64 on win32 [4s]
✔ Running postPackage hook
✔ Running preMake hook
✔ Making distributables
✔ Making a squirrel distributable for win32/x64 [33s]
✔ Running postMake hook
› Artifacts available at: D:\electron\testapp\out\make

Ahora puedes ingresar a la ruta (en mi caso) D:\electron\testapp\out y allí encontrarás dos directorios con nombre make y testapp-win32-x64, en testapp-win32-x64 están los archivos que quieres usar para distribuir tu aplicación para Windows.

Notarás que el archivo ejecutable con nombre testapp.exe no tiene el icono que definimos inicialmente, esto es lo esperado, vamos a arreglarlo editando un nuevo archivo que fue creado por Electron Forge en testapp, el archivo tiene el nombre forge.config.js, edita el archivo y agrega en la sección “packagerConfig” una línea con el siguiente contenido:

icon: 'icons/app' // no se requiere la extensión del archivo .ico

El archivo completo quedará así (recuerda que es formato JSON y se debe escribir una coma separando cada item:

forge.config.js con icono

module.exports = {
packagerConfig: {
asar: true,
icon: 'icons/app' // no se requiere la extensión del archivo .ico
},
rebuildConfig: {},
makers: [
{
name: '@electron-forge/maker-squirrel',
config: {},
},
{
name: '@electron-forge/maker-zip',
platforms: ['darwin'],
},
{
name: '@electron-forge/maker-deb',
config: {},
},
{
name: '@electron-forge/maker-rpm',
config: {},
},
],
plugins: [
{
name: '@electron-forge/plugin-auto-unpack-natives',
config: {},
},
],
};

Guarda el archivo y vuelve a ejecutar el comando para crear los archivos a distribuir:

PS D:\electron\testapp> npm run make

Una vez finalice el proceso ingresa al directorio testapp-win32-x64 y ejecuta testapp.exe verás el icono usado en la barra de tareas y en la ventana.

Hasta este punto tus archivos ya estarían listos para distribución, excepto por la firma de la aplicación si planeas distribuirla en la tienda de Microsoft, es un animal completamente fuera del alcance de esta guía, si necesitas hacerlo consulta la documentación de Microsoft para realizar el proceso.

Creando un instalador con Inno Setup para Windows

Ya que tenemos todo listo, no podemos quedar como unos desarrolladores de software vulgares que distribuyen su aplicación dentro de un .zip…

Pero cómo se te ocurre, dentro de un .zip?, nunca lo he hecho!

Inno Setup es una gran herramienta para crear instaladores en Windows, puedes descargarla desde aquí. Realiza la instalación y vamos a proceder con la creación de nuestro instalador para la aplicación.

Ejecuta Inno Setup, al iniciar será mostrada una ventana de bienvenida con algunas opciones, selecciona “Create a new script file using the Script Wizard”, dale clic al botón “OK” , en la nueva ventana mostrada dale clic a “Next”, será mostrado un formulario, escribe los datos como se muestran a continuación:

Inno Setup Script Wizard datos básicos

Dale clic a “Next” para continuar, serán mostrados algunos datos por defecto, no los cambies a menos que sepas lo que haces:

Directorio de instalación

Dale clic a “Next” nuevamente y serán solicitados los archivos a empaquetar en el instalador, en “Application main executable file:” selecciona el archivo testapp.exe creado en el directorio D:\electron\testapp\out\testapp-win32-x64.

En la sección “Other application files” dale clic al botón “Add folder” y selecciona el directorio “D:\electron\testapp\out\testapp-win32-x64”, de esta forma incluiremos todas las dependencias y archivos adicionales usados por nuestra aplicación.

Archivos a incluir en el instalador

Dale clic al botón “Next” y en el siguiente paso quita la marca a la opción “Associate a file type to the main executable” ya que no es necesario en este caso.

Asociar un tipo de archivo a la aplicación

De nuevo clic en “Next” y serán mostradas opciones para la creación de accesos directos en Windows, deja las opciones por defecto, no las cambies.

Accesos directos

Al dar clic en “Next” serán mostradas opciones para incluir licencias e información previa y posterior a la instalación, por ahora no las necesitamos, deja los valores por defecto.

Documentación del instalador

Dale clic a “Next” y serán mostradas las opciones de permisos de ejecución del instalador, esto permite al usuario decidir si se instala para todos o solo para su sesión. Deja los valores por defecto.

Modo de instalación

Al dar clic en “Next” será mostrado el selector de idiomas para el instalador, por defecto dejaremos “English”.

Selector de idiomas para el instalador

Dale clic a “Next”, serán mostradas opciones para el compilador del instalador, en el campo “Custom compiler output folder” vamos a fijar la ruta D:\electron\testapp\out\installer (crea el directorio installer dentro de out, puedes hacerlo dentro del selector de directorios de la ventana).

En el campo “Compiler output base file name” escribe “testapp” y en el campo “Custom Setup icon file” usa el icono de nuestra aplicación en la ruta D:\electron\testapp\icons\app.ico (o en la ruta donde lo tengas en tu PC)

No escribas contraseña para el instalador, no es necesario.

Opciones de compilación

Dale clic a “Next”, será mostrada una opción para la creación del script del compilador del instalador (no tienes que entenderlo pero en general, lo que indica es que el script que usará Inno Setup para generar el instalador será más o menos amigable para ser editado manualmente). Deja el valor por defecto y no hagas preguntas!.

Preprocesador de Inno Setup

Dale clic a “Next” y será mostrado el mensaje final, dale clic a “Finish” para iniciar el proceso de creación del instalador.

Paso final de creación del instalador

Al dar clic en “Finish” será mostrado el script a usar para la generación del instalador y se mostrará un mensaje preguntando si quieres realizar el proceso. Dale clic a “Sí”

Di que si!

Otra pregunta…, te preguntará si quieres guardar el script para editarlo en el futuro, dile que si y guarda en una ruta de tu preferencia.

A continuación se iniciará el proceso de creación del instalador y se mostrará el avance en la parte inferior de la ventana de Inno Setup. Una vez finalice, ve al directorio D:\electron\testapp\out\installer y encontrarás el archivo del instalador, ejecútalo y sigue los pasos.

El resultado será tu aplicación instalada en Windows tal como cualquier otra.

Lo logramos!

Y es todo, como siempre, recuerda que en Winkhosting.co somos mucho más que hosting!

--

--