Ejecutar dinámicamente JavaScript en ElectronJS

ElectronJS es un marco de código abierto que se utiliza para crear aplicaciones de escritorio nativas multiplataforma utilizando tecnologías web como HTML, CSS y JavaScript que pueden ejecutarse en los sistemas operativos Windows, macOS y Linux. Combina el motor Chromium y NodeJS en un solo tiempo de ejecución.
En Electron, cada instancia de BrowserWindow se puede considerar como una página web individual dentro de la aplicación. Electron crea y controla estas instancias de BrowserWindow mediante el objeto BrowserWindow y la propiedad webContents . En las aplicaciones web tradicionales, podemos escribir en JavaScriptcódigo dentro de la consola del navegador para que se ejecute en la página web. Para lograr lo mismo a través de scripts, necesitamos usar un complemento de navegador o una extensión. En Electron, la propiedad webContents nos proporciona ciertos métodos de instancia mediante los cuales podemos inyectar dinámicamente código JavaScript dentro de la instancia de BrowserWindow durante el tiempo de ejecución. Este tutorial demostrará cómo usar esos métodos de instancia de la propiedad webContents
Suponemos que está familiarizado con los requisitos previos que se describen en el enlace mencionado anteriormente. Para que Electron funcione, node y npm deben estar preinstalados en el sistema.

  • Estructura del proyecto: 

Project Structure

Ejemplo: Siga los pasos dados en Cree una aplicación de escritorio usando ElectronJS para configurar la aplicación electrónica básica. Copie el código estándar para el archivo main.js y el archivo index.html como se indica en el artículo. Además, realice los cambios necesarios mencionados para el archivo package.json para iniciar la aplicación Electron. Continuaremos construyendo nuestra aplicación usando la misma base de código. 

paquete.json:  

{
  "name": "electron-execute",
  "version": "1.0.0",
  "description": "Inject JS Code in Page ",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "keywords": [
    "electron"
  ],
  "author": "Radhesh Khanna",
  "license": "ISC",
  "dependencies": {
    "electron": "^8.3.0"
  }
}

Cree la carpeta de activos según la estructura del proyecto. Cree el archivo sample.txt en la carpeta de activos para fines de demostración. 
muestra.txt: 

sample.txt

Salida: en este punto, nuestra aplicación electrónica básica está configurada. Al iniciar la aplicación, deberíamos ver el siguiente resultado: 

GUI Output

Inyectar JS dinámicamente en Electron: la instancia de BrowserWindow y la propiedad webContents son parte del proceso principal . Para importar y usar BrowserWindow en el proceso Renderer , usaremos el módulo remoto Electron .
index.html: agregue el siguiente fragmento en ese archivo. 

HTML

<h3>Dynamically Inject JS</h3>
  <button id="inject">Read sample.txt File</button>
  <button id="print">Print an Array</button>

Los botones Leer archivo sample.txt e Imprimir una array todavía no tienen ninguna funcionalidad asociada. Para cambiar esto, agregue el siguiente código en el archivo index.js .
índice.js: 

Javascript

const electron = require('electron')
 
// Importing BrowserWindow from Main Process using Electron remote
const BrowserWindow = electron.remote.BrowserWindow;
 
var inject = document.getElementById('inject');
let win = BrowserWindow.getFocusedWindow();
// let win = BrowserWindow.getAllWindows()[0];
 
inject.addEventListener('click', (event) => {
    win.webContents.executeJavaScript('const path = require("path");'
        + 'const fs = require("fs");'
        + 'fs.readFile(path.join(__dirname, "../assets/sample.txt"), '
        + '{encoding: "utf-8"}, function(err, data) {'
        + 'if (!err) { console.log("received data: " + data); }'
        + 'else { console.log(err); } });', true)
        .then(console.log('JavaScript Executed Successfully'));
});
 
var print = document.getElementById('print');
print.addEventListener('click', (event) => {
 
    var webSource = {
        code: 'var numbers = [1, 2, 3, 4, 5];'
        + 'function filters(num) { return num > 2; }'
        + 'console.log(numbers.filter(filters));',
        url: '',
        startLine: 1
    }
 
    win.webContents.executeJavaScriptInIsolatedWorld(1, [webSource], true)
        .then(console.log('JavaScript Executed Successfully'));
});

Explicación: el método webContents.executeJavaScript(code, userGesture) simplemente ejecuta el código en la página web, es decir, la instancia de BrowserWindow . Este método devuelve una Promesa y se resuelve con el resultado del código ejecutado o se rechaza la Promesa si el resultado del propio código es una Promesa rechazada . Esto significa que Promise puede devolver cualquier tipo de datos, incluido un objeto, según el resultado del código ejecutado. En caso de que el código ejecutado arroje un Error, se mostrará en la consola. En caso de que el código ejecutado no devuelva una Promesapero implementa una devolución de llamada en su lugar, entonces esta Promesa se resolverá como nula como se demuestra en el código anterior. Toma los siguientes parámetros. La ejecución del código se suspenderá hasta que la página web se cargue por completo. En nuestro código, este método se invoca haciendo clic en el botón Leer archivo sample.txt .

  • código: String Este valor no puede estar vacío. Este valor representa el código que se ejecutará en la instancia de BrowserWindow . En el código anterior, hemos leído el contenido del archivo sample.txt usando el método fs.readFile() . fs.readFile () implementa una devolución de llamada y devuelve el contenido del archivo.
  • userGesture: booleano (opcional) En la instancia de BrowserWindow , algunas API HTML como requestFullScreen solo se pueden invocar mediante un gesto del usuario. Esta limitación se puede eliminar configurando la propiedad userGesture en true . El valor predeterminado es falso .

El webContents.executeJavaScriptInIsolatedWorld(worldId, scripts, userGesture) también ejecuta el código en la página web pero lo hace en un contexto aislado . Este método también devuelve una Promesa y se comporta de la misma manera que se describe para el método webContents.executeJavaScript() . Toma los siguientes parámetros. En nuestro código, este método se invoca haciendo clic en el botón Imprimir una array

  • worldId: Integer Este valor representa el ID del mundo virtual aislado para ejecutar el código JavaScript. El worldID predeterminado es 0 . La función contextIsolation de Electron utiliza 999 como ID mundial. Podemos proporcionar cualquier valor entero aquí. El código JavaScript ejecutado en este mundo virtual aislado no puede interactuar con el código de la instancia de BrowserWindow y se evalúa como un código completamente separado. Usando este método, podemos crear cualquier cantidad de mundos virtuales aislados para ejecutar diferentes segmentos del código JavaScript.
  • scripts: webSource[] Esta propiedad incluye una array de objetos webSource . Por lo tanto, este método puede ejecutar múltiples bloques de código diferentes dentro del mismo mundo. Cada objeto webSource toma los siguientes parámetros. 
    • código: String Este valor no puede estar vacío. Este valor representa el código que se ejecutará en la instancia de BrowserWindow . En el código anterior, hemos utilizado la función array.filter() para crear una nueva array que satisfaga la condición de cualquier número mayor que 2 de una array de números de muestra.
    • startLine: Integer (Opcional) El valor predeterminado es 1 . Como sugiere el nombre, este valor representa el número entero a partir del cual se debe evaluar la string de código .
  • userGesture: booleano (opcional) En la instancia de BrowserWindow , algunas API HTML como requestFullScreen solo se pueden invocar mediante un gesto del usuario. Esta limitación se puede eliminar configurando la propiedad userGesture en true . El valor predeterminado es falso .

Nota: El método webContents.executeJavaScript() puede interactuar con el código de la instancia de BrowserWindow y, por lo tanto, también podemos usar las funciones de NodeJS en el código. Por ejemplo, podemos usar la función require para importar los módulos fs y path y serán reconocidos por el código. El método webContents.executeJavaScriptInIsolatedWorld() no puede interactuar con el código de la instancia de BrowserWindow y, por lo tanto, no podemos usar las funciones de NodeJS, ya que no las reconocerá. En webContents.executeJavaScriptInIsolatedWorld()método solo podemos ejecutar código JavaScript puro del lado del cliente. En caso de que se utilicen las funciones de NodeJS, mostrará un error en la consola.

Para obtener la instancia actual de BrowserWindow en el proceso Renderer , podemos usar algunos de los métodos estáticos proporcionados por el objeto BrowserWindow .  

  • BrowserWindow.getAllWindows(): este método devuelve una array de instancias de BrowserWindow activas/abiertas. En esta aplicación, solo tenemos una instancia de BrowserWindow activa y se puede hacer referencia directamente desde la array como se muestra en el código.
  • BrowserWindow.getFocusedWindow(): este método devuelve la instancia de BrowserWindow que está enfocada en la aplicación. Si no se encuentra ninguna instancia de BrowserWindow actual, devuelve nulo . En esta aplicación, solo tenemos una instancia de BrowserWindow activa y se puede hacer referencia directamente mediante este método, como se muestra en el código.

Producción:  

Publicación traducida automáticamente

Artículo escrito por radheshkhanna y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *