0

I'm running the same function from both Electron and Node, but obtaining different results:

Invoking the function using Node from command line works fine, I get the list of connected devices:

node my_func.js

var iosDevice = require("node-ios-device");

iosDevice.devices(function (err, devices) {
  if (err) {
    console.error("Error!", err);
  } else {
    console.log(devices);
  }
});

But putting the same chunk of code in main.js in Electron (it's not in any other renderer file and it is just invoked from command line using the standard: $ npm run start), yields the following outcome:

main.js

const { app, BrowserWindow } = require("electron");
var iosDevice = require("node-ios-device");

iosDevice.devices(function (err, devices) {
  if (err) {
    console.error("Error!", err);
  } else {
    console.log(devices);
  }
});

// SET ENVIRONTMENT
process.env.NODE_ENV = "development";
// process.env.NODE_ENV = "production";

const isDev = process.env.NODE_ENV !== "production" ? true : false;
// CHECK PLATFORM
const isMac = process.platform === "darwin" ? true : false;

let mainWindow;

function createMainWindow() {
  mainWindow = new BrowserWindow({
    title: "test",
    width: 700,
    height: 195,
    icon: "./assets/icons/Icon_256x256.png",
    resizable: isDev ? true : false,
    backgroundColor: "white",
    show: false,
    webPreferences: {
      nodeIntegration: true,
      // sandbox: true,
      // contextIsolation: false,
    },
  });

  mainWindow.loadFile("./app/index.html");

  mainWindow.webContents.on("did-finish-load", function () {
    mainWindow.show();
  });
}

app.on("ready", () => {
  createMainWindow();
});

app.on("window-all-closed", () => {
  if (!isMac) {
    app.quit();
  }
});

app.on("activate", () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createMainWindow();
  }
});
  • The console does not show any result
  • Apparently, three instances of the app get created, 3 app icons pops up in Dock:

Three app icons show up

this is the package.json

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "author": "Viking",
  "license": "ISC",
  "devDependencies": {
    "electron": "^11.4.4"
  },
  "dependencies": {
    "node-ios-device": "^1.9.2"
  }
}

and requiring the npm "node-ios-device" package does not present any issue.

Any idea about how I can accomplish the same task using Electron instead Node?

Thank you.


UPDATE

After trying difference things this is the most close I got to a solution:

I moved the function to another file and I call it from the main.js file spawning a child process and invoking the function using node:

ipcMain.on("dev:getinfo", (event, options) => {
  let child_proc;
  let devices;

  child_proc = spawn("node", ["device.js"]);

  child_proc.stdout.on("data", (data) => {
    devices = `${data}`;
  });

  child_proc.on("exit", function (code, signal) {
    console.log(devices);
  });
});

And it works, in development...

but I have the feeling that it's not going to work in production since the users I'd like to distribute this app do not have Node.js installed and I don't know how I could bundle electron in such way that the users don't need to have Node.js installed.

So an issue was resolved but another one showed up

  • 1
    can you debug it and see where we're going wrong? Is the require call failing? Are you calling this code in a renderer that has node disabled? We'd need to see some more of the electron code – pushkin May 10 '21 at 22:36
  • Thank you for answering, main.js file contained the function and I just run electron with this basic command: – viking_biking May 11 '21 at 00:14
  • I've just updated the content of the original message to add a little bit more clarity, thank you – viking_biking May 11 '21 at 00:59
  • Sorry for asking. By "console", do you mean the "browser console" or the "terminal"? console.log from the main.js will not display in the browser console only in the terminal. When you call in npm run start, the electron will open up and you are probably expecting the console.log to display in the browser console. – iismaell May 11 '21 at 01:10

1 Answers1

0

Further info about my comment above...

If you want to get access to the iOSdevices from the main process to the renderer (that is the electron frontend or the webpage), try to use the webContents or the ipcMain/ipcRenderer event emitters.

   // In the main process.
    const { app, BrowserWindow } = require("electron");
    const { iosDevice } = require("node-ios-device");
    
    -- previous snips --

    let win = null
    
    app.whenReady().then(() => {
      win = new BrowserWindow({ width: 800, height: 600 })
      win.loadURL(`file://${__dirname}/index.html`)
      win.webContents.on('did-finish-load', () => {
        let devices = iosDevice.devices(function (err, devices) {
                 if (err) {
                     console.error("Error!", err);
                 } else {
                     console.log(devices);
                     return devices;
                 }
        });

        win.webContents.send('send-devices', devices);
      })
    })

Then in your index.html..

<!-- index.html -->
<html>
<body>
  <script>
    require('electron').ipcRenderer.on('send-devices', (event, message) => {
      console.log(message) // Prints the devices
    })
  </script>
</body>
</html>

// https://www.electronjs.org/docs/api/web-contents#contentssendchannel-args

iismaell
  • 623
  • 5
  • 10
  • Thank you, I expect the device list in the console too because I run the app from command line (Terminal), so I have access to that output. I tried your suggestion but I got identical result: 3 app icons popping up in the Dock and Terminal and the web browser do not show anything. – viking_biking May 11 '21 at 01:39