I'm using Node v6.2.2 and Electron v1.2.5.
I have a small application that I've built on top of Electron and now I need to fork
the process to run some long running task in another node process but it doesn't seems to work, when I'm looking at the ChildProcess
object I can see that in the argument spawnargs[0] is initialized with the electron executable instead of node so what I did is I've tried to use spawn
instead but it's not working as far as I can tell.
Here is the code I'm using to spawn
the process (lives inside the file ./modules/tester.js
):
const {spawn} = require('child_process');
var child = spawn("node", ["worker.js"], { stdio: ['inherit', 'inherit', 'inherit', 'ipc'] });
const self = {};
self.start = () => {
console.log("start");
child.send("ping");
};
And here is the code I'm using for my worker.js
file:
process.on("message", (data) => {
console.log(data);
console.log("pong");
});
And finally this is how I'm consuming it.
const {app} = require("electron");
const tester = require("./modules/tester");
app.on("ready", () => {
tester.start();
});
Maybe I'm doing it wrong but I don't think so because when I'm using nodejs it seems to work just fine.
I've tried many examples but none of them seems to work, another possibility is that I need to do something special in Electron for it to work but I don't know.
Spawned Child Processes. The spawn function launches a command in a new process and we can use it to pass that command any arguments. For example, here's code to spawn a new process that will execute the pwd command. const { spawn } = require('child_process'); const child = spawn('pwd');
To make Electron usable within a child process, we'll need to call spawn instead of fork : const { spawn } = require('child_process'); spawn(process. execPath, [ path. join(__dirname, 'child.
Node. js also provides a way to create a child process that executes other Node. js programs. Let's use the fork() function to create a child process for a Node.
A child process is a process created by a parent process in operating system using a fork() system call. A child process may also be called a subprocess or a subtask. A child process is created as its parent process's copy and inherits most of its attributes.
Finally, I've solved it.
The way I solved this is doing exactly the reverse, NodeJS is available on the production machines so I just wrote a start.js
script that basically spawn a child process to run Electron and on the parent process I'm running this long running task and finally I'm using IPC to communicate between the two processes.
This answer would suit your app if it is a Portable .exe. I haven't myself worked with an installable one so don't know much about that.
Creating a child process while doing development is really easy. Simplest is using fork()
from Node's child_process
(Though we can use any of spawn/exec/execFile... etc depending on what we want).
The tough part comes when we pack the application as an Executable which contains the packaged files as "app.asar".
The key point is, do you understand what "app.asar" is? "app.asar" on a normal glance will look like a normal bundled file but it actually is a Virtual Directory, this means you can traverse inside it as you would with any other directory, maybe just consider it as a directory name. If you would do __dirname
under the main process of the electron code you would see the location as '/path/to/app.asar'.
How do you see what is inside "app.asar"? - reference
fs.readdirSync('/path/to/app.asar')
Answer
You need to bundle/copy the file (the file which will run on a separate process, say filename is: "child.process.js") separately into the folder from which your packager (like: electron-builder) is creating the EXE. Let's say you package everything under a "dist" folder, then this dist folder should have the file child.process.js. Now this "dist" folder itself will become "app.asar".
When you specify the path of child.process.js
for the fork()
and if the file "child.process.js" lies directly inside dist
, give it like:
fork(path.join(__dirname, 'child.process.js'))
If there it present under subdirectories, then give the appropriate path.
The interesting thing is, the above code works both while using it as a portable EXE and while development(If you bundle all the main process files into one file.)
It took me 3 days to figure this out. How I did my debugging while testing the EXE? I used fs
to write to files and later opened them and read their contents. I only realized the solution when I printed the output of fs.readdirSync('/path/to/app.asar')
. The funny thing was I had two dist folders and I was packaging my child file for local development dist but wasn't doing it for the dist from which I was packaging the App.
Hope this helps somebody!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With