fbpixel
Etiquetas:

En este tutorial veremos cómo crear una aplicación de escritorio utilizando el framework Electron. Este entorno de programación le permite desarrollar interfaces gráficas de usuario utilizando los lenguajes Web JavaScript, HTML y CSS que son compatibles en varios sistemas operativos.

Configuración del entorno de programación

Para este tutorial, utilizaremos el editor de código VS Code.

El framework Electron funciona con el software Node.js. Descargue e instale la última versión

o introduzca los siguientes comandos en Linux

sudo apt-get install nodejs npm

Compruebe las versiones instaladas. Esto le ayudará a comprobar la compatibilidad de las bibliotecas.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
node -v
npm -v
node -v npm -v
node -v
npm -v

En el terminal VSCode, cree su directorio de trabajo

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
mkdir ElectronApp && cd ElectronApp
mkdir ElectronApp && cd ElectronApp
mkdir ElectronApp && cd ElectronApp

En el directorio de la aplicación, introduzca el comando de inicialización para crear los archivos por defecto

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm init
npm init
npm init

Introduzca la información solicitada. Tenga en cuenta que Electron toma el archivo main.js como punto de entrada.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Press ^C at any time to quit.
package name: (electronapp)
version: (1.0.0)
description: custom electron app for dev and tutorials
entry point: (index.js) main.js
test command:
git repository:
keywords:
author: aranacorp
license: (ISC) MIT
About to write to D:\Formation\Javascript\Electron\ElectronApp\package.json:
{
"name": "electronapp",
"version": "1.0.0",
"description": "custom electron app for dev and tutorials",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"author": "aranacorp",
"license": "MIT"
}
Press ^C at any time to quit. package name: (electronapp) version: (1.0.0) description: custom electron app for dev and tutorials entry point: (index.js) main.js test command: git repository: keywords: author: aranacorp license: (ISC) MIT About to write to D:\Formation\Javascript\Electron\ElectronApp\package.json: { "name": "electronapp", "version": "1.0.0", "description": "custom electron app for dev and tutorials", "main": "main.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "electron ." }, "author": "aranacorp", "license": "MIT" }
Press ^C at any time to quit.
package name: (electronapp)
version: (1.0.0)
description: custom electron app for dev and tutorials
entry point: (index.js) main.js
test command:
git repository:
keywords:
author: aranacorp
license: (ISC) MIT
About to write to D:\Formation\Javascript\Electron\ElectronApp\package.json:

{
  "name": "electronapp",
  "version": "1.0.0",
  "description": "custom electron app for dev and tutorials",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "electron ."
  },
  "author": "aranacorp",
  "license": "MIT"
}

A continuación, puede instalar el electrón

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install --save-dev electron
npm install --save-dev electron
npm install --save-dev electron

Una vez creado el archivo package.json, añada la siguiente línea a los scripts

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
"start": "electron ."
"start": "electron ."
    "start": "electron ."

Este scirpt se utiliza para lanzar la aplicación con el comando

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm start
npm start
npm start

Creación de la primera aplicación Electron

En este ejemplo, vamos a recuperar las versiones de node y electron como en el tutorial básico. También vamos a añadir un campo de entrada para definir una posible URL.

Para crear la aplicación, vamos a crear 5 archivos

  • main.js gestiona el ciclo de vida de la aplicación
  • index.html contiene la página HTML
  • ./src/ac_style.css contiene el estilo de la página HTML
  • precargar.js contiene el script de precarga, incluidas las funciones de comunicación entre procesos
  • renderer.js contiene las funciones que gestionan la página HTML
  • main.js
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
//icon:'./src/logo_araignee.png',
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
ipcMain.on('set-url', (event, url) => {
console.log("url set to: ",url)
})
//win.webContents.openDevTools() //Open devtools on launch
win.setTitle(app.getName()+"@"+app.getVersion());
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => { //for macOS
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
const { app, BrowserWindow, ipcMain } = require('electron') const path = require('node:path') const createWindow = () => { const win = new BrowserWindow({ width: 800, height: 600, //icon:'./src/logo_araignee.png', webPreferences: { preload: path.join(__dirname, 'preload.js') } }) ipcMain.on('set-url', (event, url) => { console.log("url set to: ",url) }) //win.webContents.openDevTools() //Open devtools on launch win.setTitle(app.getName()+"@"+app.getVersion()); win.loadFile('index.html') } app.whenReady().then(() => { createWindow() app.on('activate', () => { //for macOS if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit() })
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')

const createWindow = () => {
    const win = new BrowserWindow({
      width: 800,
      height: 600,
      //icon:'./src/logo_araignee.png',
      webPreferences: {
        preload: path.join(__dirname, 'preload.js')
      }
    })

    ipcMain.on('set-url', (event, url) => {
        console.log("url set to: ",url)
      })

    //win.webContents.openDevTools() //Open devtools on launch
    win.setTitle(app.getName()+"@"+app.getVersion());
    win.loadFile('index.html')
  }

  app.whenReady().then(() => {
    createWindow()

    app.on('activate', () => { //for macOS
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
      })
  })

  app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
  })

  • index.html
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<link rel="stylesheet" href="./src/ac_style.css">
</head>
<body>
<h1>Hello World!</h1>
<p>Nous utilisons les versions: </p>
<ul>
<li>Node.js : <span id="node-version"></span></li>
<li>Chromium : <span id="chrome-version"></span></li>
<li>Electron : <span id="electron-version"></span></li>
</ul>
<p>CurrentURL: <span id="current-url">None</span></p>
<p>URL: <input id="url"/> <button id="btn" type="button">Set</button></p>
<script src="./renderer.js"></script>
</body>
</html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP --> <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'"> <link rel="stylesheet" href="./src/ac_style.css"> </head> <body> <h1>Hello World!</h1> <p>Nous utilisons les versions: </p> <ul> <li>Node.js : <span id="node-version"></span></li> <li>Chromium : <span id="chrome-version"></span></li> <li>Electron : <span id="electron-version"></span></li> </ul> <p>CurrentURL: <span id="current-url">None</span></p> <p>URL: <input id="url"/> <button id="btn" type="button">Set</button></p> <script src="./renderer.js"></script> </body> </html>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
	<link rel="stylesheet" href="./src/ac_style.css">
  </head>
  <body>
    <h1>Hello World!</h1>
    <p>Nous utilisons les versions: </p>
    <ul>
      <li>Node.js : <span id="node-version"></span></li>
      <li>Chromium : <span id="chrome-version"></span></li>
      <li>Electron : <span id="electron-version"></span></li>
  </ul>
  <p>CurrentURL: <span id="current-url">None</span></p>
  <p>URL: <input id="url"/> <button id="btn" type="button">Set</button></p>
  <script src="./renderer.js"></script>
  </body>
</html>
  • ./src/ac_style.css
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
:root {
--bg-color: #161616;
--btn-color: #346751;
--title-color: #3aaa35; /*#c84b31; #ff9900*/
--text-color: #ecdbba;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
h1 {
color: var(--title-color);
}
p {
font-size: 18px;
margin-bottom: 20px;
}
:root { --bg-color: #161616; --btn-color: #346751; --title-color: #3aaa35; /*#c84b31; #ff9900*/ --text-color: #ecdbba; } body { background-color: var(--bg-color); color: var(--text-color); font-family: Arial, sans-serif; margin: 0; padding: 0; } h1 { color: var(--title-color); } p { font-size: 18px; margin-bottom: 20px; }
:root {
  --bg-color: #161616;
  --btn-color: #346751;
  --title-color: #3aaa35; /*#c84b31; #ff9900*/
  --text-color: #ecdbba;
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}

h1 {
  color: var(--title-color);
}

p {
  font-size: 18px;
  margin-bottom: 20px;
}
  • preload.js
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
setURL: (url) => ipcRenderer.send('set-url', url)
})
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
const { contextBridge, ipcRenderer } = require('electron') contextBridge.exposeInMainWorld('electronAPI', { setURL: (url) => ipcRenderer.send('set-url', url) }) window.addEventListener('DOMContentLoaded', () => { const replaceText = (selector, text) => { const element = document.getElementById(selector) if (element) element.innerText = text } for (const dependency of ['chrome', 'node', 'electron']) { replaceText(`${dependency}-version`, process.versions[dependency]) } })
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
  setURL: (url) => ipcRenderer.send('set-url', url)
})

window.addEventListener('DOMContentLoaded', () => {
    const replaceText = (selector, text) => {
      const element = document.getElementById(selector)
      if (element) element.innerText = text
    }
    for (const dependency of ['chrome', 'node', 'electron']) {
      replaceText(`${dependency}-version`, process.versions[dependency])
    }
  })
  • renderer.js
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const urlInput = document.getElementById('url')
const currURL = document.getElementById('current-url')
const setButton = document.getElementById('btn')
setButton.addEventListener('click', () => {
const url = urlInput.value
window.electronAPI.setURL(url)
currURL.innerHTML = url
})
const urlInput = document.getElementById('url') const currURL = document.getElementById('current-url') const setButton = document.getElementById('btn') setButton.addEventListener('click', () => { const url = urlInput.value window.electronAPI.setURL(url) currURL.innerHTML = url })
const urlInput = document.getElementById('url')
const currURL = document.getElementById('current-url')

const setButton = document.getElementById('btn')
setButton.addEventListener('click', () => {
  const url = urlInput.value
  window.electronAPI.setURL(url)
  currURL.innerHTML = url
})

Resultados

Una vez lanzado el script mediante «npm start», se abrirá una ventana. Puedes actualizar la URL utilizando el campo de entrada y el botón «Set».

electron-first-application-1 Creación de una aplicación de escritorio con Electron

Crear un ejecutable para la aplicación

Para crear el ejecutable utilizamos el paquete electron-packager

npm install --save-dev electron-packager

A continuación, puede compilar su proyecto utilizando el comando

npx electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> [optional flags...]

Ejemplo para Windows

npx electron-packager . myElectronApp --overwrite --asar --platform=win32 --arch=x64 --icon=./src/logo_araignee.ico --prune=true --out=release-builds

Ejemplo para Linux

npx electron-packager . myElectronApp --overwrite --asar --platform=linux --arch=x64 --icon=./src/logo_araignee.ico --prune=true --out=release-builds
OSplatform architecture
Windowswin32x86, x86_64, and arm64
Linuxlinuxx86, x86_64, armv7l, arm64, and mips64el
macOSdarwinx86_64, arm64, and universal

En el archivo package.json, añade estos dos scripts como accesos directos;

    "build": "electron-packager . myElectronApp --overwrite",
    "clean": "rm -rf release-builds"

Puede crear un ejecutable con el comando

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm run build
npm run build
npm run build

o eliminar carpetas generadas con

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm run clean
npm run clean
npm run clean

Ahora puede iniciar la aplicación desde el archivo ejecutable myElectronApp.exe

electron-packager-first-application Creación de una aplicación de escritorio con Electron

Bonificación: Creación de una aplicación con Electron y React

Vamos a crear la misma aplicación con Electron y React. Para ello, creamos un nuevo proyecto

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm init electron-app@latest react-electron-app -- --template=webpack
npm init electron-app@latest react-electron-app -- --template=webpack
npm init electron-app@latest react-electron-app -- --template=webpack
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
cd react-electron-app
cd react-electron-app
cd react-electron-app
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install --save-dev @babel/core @babel/preset-react babel-loader
npm install --save-dev @babel/core @babel/preset-react babel-loader
npm install --save-dev @babel/core @babel/preset-react babel-loader

A continuación, modifique el archivo webpack.rules.js

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
test: /\.jsx?$/,
use: {
loader: 'babel-loader',
options: {
exclude: /node_modules/,
presets: ['@babel/preset-react']
}
}
}
{ test: /\.jsx?$/, use: { loader: 'babel-loader', options: { exclude: /node_modules/, presets: ['@babel/preset-react'] } } }
  {
    test: /\.jsx?$/,
    use: {
      loader: 'babel-loader',
      options: {
        exclude: /node_modules/,
        presets: ['@babel/preset-react']
      }
    }
  }

npm install -save react react-dom

  • index.html
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World!</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello World!</title> </head> <body> <div id="root"></div> </body> </html>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World!</title>

  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
  • renderer.js
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./app.jsx";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
import React from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; import App from "./app.jsx"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <React.StrictMode> <App /> </React.StrictMode> );
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./app.jsx";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
  • app.jsx
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
url: "None",
};
}
setUrl = () => {
//() => {this.setState({url: document.getElementById("url").value})}
this.setState({url: document.getElementById("url").value})
}
render() {
return (
<div>
<h1>Hello World!</h1>
<p>Welcome to your Electron application.</p>
<p>CurrentURL: <span id="current-url">{this.state.url}</span></p>
<p>URL: <input id="url" /> <button id="btn" type="button" onClick={this.setUrl}>Set</button></p>
</div>
);
}
}
export default App;
import React from "react"; class App extends React.Component { constructor(props) { super(props); this.state = { url: "None", }; } setUrl = () => { //() => {this.setState({url: document.getElementById("url").value})} this.setState({url: document.getElementById("url").value}) } render() { return ( <div> <h1>Hello World!</h1> <p>Welcome to your Electron application.</p> <p>CurrentURL: <span id="current-url">{this.state.url}</span></p> <p>URL: <input id="url" /> <button id="btn" type="button" onClick={this.setUrl}>Set</button></p> </div> ); } } export default App;
import React from "react";

class App extends React.Component {
  constructor(props) {    
        super(props);    
        this.state = {      
            url: "None",    
        };  
    }

    setUrl = () => {
        //() => {this.setState({url: document.getElementById("url").value})}
        this.setState({url: document.getElementById("url").value})
    }

    render() {
    return (
        <div>
        
        <h1>Hello World!</h1>
        <p>Welcome to your Electron application.</p>
        <p>CurrentURL: <span id="current-url">{this.state.url}</span></p>
        <p>URL: <input id="url" /> <button id="btn" type="button" onClick={this.setUrl}>Set</button></p>
    
        </div>
    );
    }
}

export default App;

A continuación, puede iniciar la aplicación con el comando

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm start
npm start
npm start

Para crear el ejecutable

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm run make
npm run make
npm run make

Fuentes