Can we launch a node command on a mac without node installed when using electron-packager?
Asked Answered
R

1

1

When I package an electron app using electron-packager. The app spawns a child process which uses a 'node' command. Now if I try to launch my app in a system with no node installed on it, does the app work?

I have been trying to achieve this and facing various issues, the electron community suggested me to use fork method, spawn method with 'Process.execPath' as command and also setting the ELECTRON_RUN_AS_NODE variable but nothing seems to work on my end.

Now after doing all this I question myself, do I definitely need node installed on my system to run the app? or is there really a way that can pass the parent environment(which I believe has node) to the child process? If yes what am I missing here?

Something to note, I am using 'fixpath()' to set the $PATH on macOS when run from a GUI app. Not sure if this is messing up something in my code. https://www.npmjs.com/package/fix-path

Please find my code below:

'use strict'
 const fixPath = require('fix-path');

 let func = () => {
   fixPath();   
   const child = childProcess.exec('node scriptPath --someFlags', {
     detached: true, 
     stdio: 'ignore',
     env: {
       ELECTRON_RUN_AS_NODE: 1,
     }
 });
 child.on('error', (err) => {
   console.log("\n\t\tERROR: spawn failed! (" + err + ")");
 });

 child.stderr.on('data', function(data) {
   console.log('stdout: ' +data);
 });

 child.on('exit', (code, signal) => {
   console.log(code);
   console.log(signal);
 });

 child.unref();
 }
Receptacle answered 9/8, 2018 at 16:15 Comment(15)
If you are using electron builder or some other electron packaging tool, then the node is all built-in to the installer/unpack. You do not need to have node installed to execute a forked process. It is already included.... You should be able to do .... require('child_process').execSync('mycommand.exe');Bevatron
Can you tell me what's going wrong in my code?Receptacle
When you console.log fixPath() on line 5 of your example ... what do you get? Also what are you putting where it says, scriptPath ?Bevatron
console.log fixPath() prints undefined and I keep the path to the script through scriptPath.Receptacle
Im confused.... What is "scriptPath" ... you need to specify the location path inside the childProcess.exec so the node can execute it... Where is the actual node script located on your filesystem?Bevatron
Yes I specify the location of my file in the exec method like exec('node /src/script.js')Receptacle
Does the child process error out inside the child.on('error' .... ?Bevatron
No, the child process exits immediately with 127 exit code, saying /bin/bash: node command not found. I use stdout.on to catch this.Receptacle
Just for the sake of testing try this... childProcess.exec('/usr/local/bin/node scriptPathBevatron
That doesn't work, still gives the node not found error as node is not installed in the system.Receptacle
If you are trying to execute a JS script you as a child process you should try using fork method. const fork = require('child_process').fork;Bevatron
const fork = require('child_process').fork; const scriptPath = path.resolve('/path/to/my/script/myFileToExec.js'); const myScript = fork(scriptPath, null, { stdio: [ 'pipe', 'pipe', 'pipe', 'ipc' ] });Bevatron
I tried using fork, when I use fork the process exits immediately with exit code 1 which I am unable to catch. Is there a way I can catch the error when using fork? When I use exec method I have stdout.on to catch it, but for fork nothing works.Receptacle
myScript.on('exit', function (code, signal) {})Bevatron
That just gives me the exit code 1 and signal null, I don't get any other info.Receptacle
R
3

Yes, we can run a packaged app which runs a child node process even on a system with no node installed. One can use 'fork' method to run a node process and by setting the ELECTRON_RUN_AS_NODE env variable. Please find the sample code below.

 let func = () => {
   const child = childProcess.fork(path, args, 
   {
     detached: true, 
     stdio: 'ignore',
     env: {
        ELECTRON_RUN_AS_NODE: 1
     }
   }

 });

 child.on('error', (err) => {
   console.log("\n\t\tERROR: spawn failed! (" + err + ")");
 });

 child.on('exit', (code, signal) => {
   console.log(code);
   console.log(signal);
 });

 child.unref();
Receptacle answered 28/8, 2018 at 20:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.