TUTORIAL COMPLETO: Crear Software de Escritorio con Electron

📋 ÍNDICE DEL TUTORIAL

  1. Requisitos Previos
  2. Estructura del Proyecto
  3. Configuración Paso a Paso
  4. Solución de Errores Comunes
  5. Distribución del Software

🛠 REQUISITOS PREVIOS

Paso 1: Instalar Node.js

¿Qué es? Node.js es el entorno de ejecución que necesitamos para usar Electron.

Cómo instalarlo:

  1. Ve a nodejs.org
  2. Descarga la versión LTS (recomendada)
  3. Instala con configuración por defecto

Verificar instalación:

node --version
npm --version

Explicación:

  • node --version → Muestra la versión de Node.js instalada
  • npm --version → Muestra la versión del gestor de paquetes
  • Si muestran números de versión, está correctamente instalado

🚀 ESTRUCTURA DEL PROYECTO

Paso 2: Crear Carpeta del Proyecto

¿Por qué? Necesitamos un lugar organizado para todos nuestros archivos.

Comandos:

C:
mkdir mi-software
cd mi-software

Explicación:

  • C: → Cambia a la unidad C: (donde normalmente trabajamos)
  • mkdir mi-software → Crea una carpeta llamada «mi-software»
  • cd mi-software → Entra en la carpeta recién creada

Para otros proyectos: Solo cambia «mi-software» por el nombre que quieras.


📦 CONFIGURACIÓN PASO A PASO

Paso 3: Inicializar Proyecto Node.js

¿Qué hace? Crea el archivo package.json que contiene la configuración del proyecto.

Comando:

npm init -y

Explicación:

  • npm → Node Package Manager (gestor de paquetes)
  • init → Inicializa un nuevo proyecto
  • -y → Acepta todas las configuraciones por defecto

Resultado: Crea package.json con esta estructura básica:

{
  "name": "mi-software",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Paso 4: Instalar Electron

¿Qué es Electron? Framework que convierte HTML/CSS/JS en aplicaciones de escritorio.

Comando:

npm install --save-dev electron

Explicación:

  • install → Instala un paquete
  • --save-dev → Guarda como dependencia de desarrollo
  • electron → El paquete que queremos instalar

Paso 5: Instalar Electron-Builder

¿Qué hace? Crea instaladores y ejecutables de nuestra aplicación.

Comando:

npm install --save-dev electron-builder

📄 CREACIÓN DE ARCHIVOS

Paso 6: Crear main.js (Archivo Principal)

¿Qué es? El punto de entrada de la aplicación Electron.

Comando para crear:

notepad main.js

Contenido COMPLETO y EXPLICADO:

// Importar módulos necesarios de Electron
const { app, BrowserWindow } = require('electron');
const path = require('path');

// SOLUCIÓN PARA PROBLEMAS DE GPU - INICIO
// Estas líneas previenen errores gráficos
app.disableHardwareAcceleration();
app.commandLine.appendSwitch('--disable-gpu');
app.commandLine.appendSwitch('--disable-gpu-compositing');
// SOLUCIÓN PARA PROBLEMAS DE GPU - FIN

// Función para crear la ventana principal
function createWindow() {
  // Crear la ventana del navegador
  const mainWindow = new BrowserWindow({
    width: 1200,           // Ancho de la ventana
    height: 800,           // Alto de la ventana
    webPreferences: {      // Configuración CRÍTICA para que todo funcione
      nodeIntegration: true,        // Permite usar Node.js en el frontend
      contextIsolation: false,      // Necesario para que los inputs funcionen
      enableRemoteModule: true,     // Habilita módulos remotos
      webSecurity: false,           // IMPORTANTE: Permite inputs funcionen
      allowRunningInsecureContent: true // Permite contenido mixto
    },
    // Configuración adicional de la ventana
    resizable: true,       // Permite redimensionar
    movable: true,         // Permite mover la ventana
    minimizable: true,     // Permite minimizar
    maximizable: true,     // Permite maximizar
    focusable: true,       // Permite recibir focus
    alwaysOnTop: false     // No siempre encima de otras ventanas
  });

  // Cargar el archivo HTML principal
  mainWindow.loadFile('index.html');

  // SOLUCIÓN PARA ENFOQUE DE VENTANA - INICIO
  // Asegura que la ventana reciba focus correctamente
  mainWindow.once('ready-to-show', () => {
    mainWindow.show();     // Mostrar ventana
    mainWindow.focus();    // Enfocar ventana
  });
  // SOLUCIÓN PARA ENFOQUE DE VENTANA - FIN
}

// Cuando la aplicación está lista, crear la ventana
app.whenReady().then(createWindow);

// Manejar cierre de todas las ventanas
app.on('window-all-closed', () => {
  // En Windows y Linux, salir cuando se cierran todas las ventanas
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

// Manejar reactivación en macOS
app.on('activate', () => {
  // En macOS, recrear ventana si se hace clic en el dock
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

Explicación de conceptos importantes:

  • BrowserWindow: Crea ventanas del navegador
  • webPreferences: Configura cómo se comporta el contenido web
  • nodeIntegration: Permite usar require() en el frontend
  • contextIsolation: Debe ser false para que los inputs funcionen

Paso 7: Crear index.html (Tu Aplicación)

Comando:

notepad index.html

Para TU código específico:

  • Pega TODO tu código HTML original
  • Luego aplica las MODIFICACIONES OBLIGATORIAS siguientes:

MODIFICACIONES OBLIGATORIAS en tu HTML:

1. Agregar este CSS en la sección <style>:

/* === SOLUCIÓN PARA INPUTS EN ELECTRON === */
/* Permitir interacción con elementos de formulario */
input, select, textarea, button {
  -webkit-user-select: auto !important;
  -webkit-user-drag: auto !important;
  -webkit-app-region: no-drag !important;
  cursor: text !important;
}

/* Mejorar el focus visual en inputs */
.form-control:focus {
  border-color: #3498db !important;
  box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25) !important;
  outline: none !important;
}

/* Configuración base del body */
body {
  -webkit-user-select: none;   /* No seleccionar texto normal */
  user-select: none;
  cursor: default;
}

/* Pero PERMITIR selección en inputs y textareas */
input, textarea, [contenteditable="true"] {
  -webkit-user-select: text !important;
  user-select: text !important;
  cursor: text !important;
}

/* Asegurar que los botones sean clickeables */
button, .btn, [role="button"] {
  cursor: pointer !important;
  -webkit-app-region: no-drag !important;
}

2. Agregar este JavaScript ANTES de </body>:

<script>
// === SOLUCIÓN COMPLETA PARA INTERACCIÓN EN ELECTRON ===

// Cuando el documento está listo
document.addEventListener('DOMContentLoaded', function() {
  console.log('Aplicación cargada - Soluciones Electron aplicadas');

  // Solución 1: Forzar focus en elementos interactivos
  document.addEventListener('click', function(e) {
    const interactiveElements = ['input', 'select', 'textarea', 'button', 'a', '[role="button"]'];

    if (interactiveElements.some(selector => e.target.matches(selector))) {
      e.target.focus();
      e.stopPropagation();
    }
  });

  // Solución 2: Prevenir selección de texto no deseada
  document.addEventListener('selectstart', function(e) {
    if (!e.target.matches('input, textarea, [contenteditable="true"]')) {
      e.preventDefault();
    }
  });

  // Solución 3: Habilitar arrastre solo donde sea necesario
  document.addEventListener('dragstart', function(e) {
    if (!e.target.matches('input, textarea, [draggable="true"]')) {
      e.preventDefault();
    }
  });

  // Solución 4: Timeout de seguridad para problemas de renderizado
  setTimeout(() => {
    document.body.style.pointerEvents = 'auto';
    // Forzar reflow para asegurar renderizado
    document.body.style.display = 'none';
    document.body.offsetHeight; // Trigger reflow
    document.body.style.display = 'block';
  }, 100);
});

// Solución 5: Manejar doble clic en inputs
document.addEventListener('dblclick', function(e) {
  if (e.target.matches('input, textarea')) {
    e.target.select(); // Seleccionar todo el texto
  }
});

// Solución 6: Prevenir comportamiento por defecto en context menu
document.addEventListener('contextmenu', function(e) {
  if (e.target.matches('input, textarea')) {
    e.preventDefault(); // Permitir menú contextual en inputs
  }
});
</script>

Paso 8: Actualizar package.json

Comando:

notepad package.json

Reemplazar TODO el contenido con:

{
  "name": "gestor-stand-comercial",
  "version": "1.0.0",
  "description": "Sistema de gestión completo para stand comercial con control de inventario, ventas y empleados",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "build": "electron-builder",
    "dist": "electron-builder --publish=never"
  },
  "keywords": [
    "gestor",
    "stand",
    "comercial", 
    "ventas",
    "inventario",
    "empleados",
    "contabilidad"
  ],
  "author": "Tu Nombre",
  "license": "MIT",
  "build": {
    "appId": "com.tuempresa.gestorstand",
    "productName": "Gestor Stand Comercial",
    "directories": {
      "output": "dist"
    },
    "files": [
      "**/*",
      "!node_modules",
      "!dist"
    ],
    "win": {
      "target": "nsis",
      "icon": "assets/icon.ico"
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true,
      "createDesktopShortcut": true,
      "createStartMenuShortcut": true,
      "shortcutName": "Gestor Stand Comercial"
    }
  },
  "devDependencies": {
    "electron": "^27.0.0",
    "electron-builder": "^24.6.4"
  }
}

Explicación de campos importantes:

  • name: Nombre interno del proyecto
  • productName: Nombre que verá el usuario
  • appId: Identificador único (cambia «tuempresa» por tu nombre)
  • files: Qué archivos incluir en el instalador
  • nsis: Configuración del instalador Windows

🧪 PRUEBA Y CONSTRUCCIÓN

Paso 9: Probar la Aplicación

Comando:

npm start

Qué esperar:

  • Se abre una ventana con tu aplicación
  • Los inputs deben funcionar correctamente
  • Los botones deben ser clickeables
  • No deberían aparecer errores en la consola

Paso 10: Crear el Instalador

Comando:

npm run dist

Proceso:

  1. Electron-builder empaca tu aplicación
  2. Crea un instalador Windows (.exe)
  3. Lo guarda en la carpeta dist/

Verificar resultado:

dir dist

Deberías ver tu archivo .exe


⚠️ SOLUCIÓN DE ERRORES COMUNES

ERROR 1: Problemas de GPU

Mensajes típicos:

GPU process exited unexpectedly
exit_code=-10737/40791
ContextResult::kTransientFailure

Causa: Problemas con la aceleración por hardware

Solución (YA INCLUIDA en main.js):

app.disableHardwareAcceleration();
app.commandLine.appendSwitch('--disable-gpu');

ERROR 2: Inputs no funcionan

Síntomas: No se puede escribir en campos de texto, no se pueden hacer clics

Causa: Configuración incorrecta de webPreferences

Solución (YA INCLUIDA):

webPreferences: {
  nodeIntegration: true,
  contextIsolation: false,  // ← ESTO ES CRÍTICO
  webSecurity: false,       // ← ESTO ES CRÍTICO  
  enableRemoteModule: true
}

ERROR 3: Aplicación no se enfoca

Solución (YA INCLUIDA):

mainWindow.once('ready-to-show', () => {
  mainWindow.show();
  mainWindow.focus();  // ← Forzar enfoque
});

ERROR 4: Vulnerabilidades npm

Mensaje: X moderate severity vulnerability

Solución:

npm audit fix

O si persiste:

npm audit fix --force

📦 DISTRIBUCIÓN DEL SOFTWARE

Paso 11: Instalar y Distribuir

  1. Encuentra el instalador: En carpeta dist/
  2. Nómbre típico: Gestor Stand Comercial Setup 1.0.0.exe
  3. Para instalar: Doble clic en el .exe y seguir instrucciones
  4. Para distribuir: Copiar el .exe a otras computadoras

Paso 12: Personalización Avanzada

Cambiar icono:

  1. Crear imagen 256×256 píxeles
  2. Convertir a .ico
  3. Guardar como assets/icon.ico
  4. Recompilar: npm run dist

Cambiar información:
Editar package.json:

  • name
  • description
  • author
  • productName

🔄 FLUJO DE TRABAJO PARA NUEVOS PROYECTOS

Para crear OTRO software diferente:

  1. Sigue los mismos pasos 1-10
  2. En el Paso 7, en lugar de pegar el HTML del ejemplo, pega TU código HTML
  3. NO OLVIDES aplicar las modificaciones CSS y JavaScript obligatorias
  4. En package.json, cambia:
  • name
  • description
  • productName
  • appId

Comandos rápidos para nuevos proyectos:

# 1. Crear carpeta
mkdir nuevo-proyecto
cd nuevo-proyecto

# 2. Inicializar
npm init -y

# 3. Instalar dependencias
npm install --save-dev electron electron-builder

# 4. Crear archivos (copiar main.js y package.json de este tutorial)
# 5. Agregar tu HTML con las modificaciones
# 6. Probar y construir
npm start
npm run dist

🎯 RESUMEN FINAL

Archivos CRÍTICOS que debes tener:

  1. main.js → Configuración de Electron (CON LAS SOLUCIONES)
  2. index.html → Tu aplicación (CON LAS MODIFICACIONES)
  3. package.json → Configuración del proyecto

Pasos OBLIGATORIOS para que funcione:

  1. ✅ Configuración correcta en main.js
  2. ✅ CSS de solución en tu HTML
  3. ✅ JavaScript de solución en tu HTML
  4. contextIsolation: false en webPreferences

Para verificar que todo funciona:

  1. Ejecuta npm start
  2. Prueba: hacer clic en inputs, escribir texto, usar botones
  3. Si todo responde, ejecuta npm run dist


Descubre más desde Clasenet

Suscríbete y recibe las últimas entradas en tu correo electrónico.

Miguel Ángel Urbaez
Miguel Ángel Urbaez
Artículos: 108

Deja un comentario