I have an electron app where I need not only to run the interface to the user but also start an express server that will serve files for people connected through the network.
I have everything working if I start both electron and the express server normally, but I'm pretty confident that I will need the server running in a different thread to avoid slugish interface and even problems with the server.
For that matter I tried to run my express server using the child_process.fork and it worked when I use npm start
, but when I use electron-builder
to create an .exe, the installed program doesn't start the express server.
I tried to run my server right away using:
require('child_process').fork('app/server/mainServer.js')
I tried several changes, prefixing the file with __dirname
, process.resourcesPath
and even hard coding the generated file path; changing the fork options to pass cwd: __dirname
, detached: true
and stdio: 'ignore'
; and even tried using spawn
with process.execPath
, which will also work with npm start
but won't when packaged (it keeps opening new instances of my app, seems obvious after you do hehe)
Note: If I don't fork and require the server script right away, using require('server/mainServer.js')
it works on the packaged app, so the problem most like isn't the express itself.
Note 2: I have asar: false
to solve other problems, so this is not the problem solver here.
I put up a small git project to show my problem:
https://github.com/victorivens05/electron-fork-error
Any help will be highly appreciated.
To use Electron, you need to install Node. js. We recommend that you use the latest LTS version available.
With the great help from Samuel Attard (https://github.com/MarshallOfSound) I was able to solve the problem (he solved for me actually)
As he said:
the default electron app will launch the first file path provided to it
so `electron path/to/thing` will work
in a packaged state, that launch logic is not present
it will always run the app you have packaged regardless of the CLI args passed to it
you need to handle the argument manually yourself
and launch that JS file if it's passed in as the 1st argument
The first argument to fork simply calls `process.execPath` with the first
argument being the path provided afaik
The issue is that when packaged Electron apps don't automatically run the
path provided to them
they run the app that is packaged within them
In other words. fork
is actually spawn
being executed with process.execPath
and passing the fork's first argument as the second for spawn.
What happens in a packaged app is that the process.execPath
isn't electron but the packaged app itself. So if you try to spawn
, the app will be open over and over again.
So, what Samuel suggest was implemented like this:
if (process.argv[1] === '--start-server') {
require('./server/mainServer.js')
return
}
require('./local/mainLocal.js')
require('child_process').spawn(process.execPath, ['--start-server'])
That way, the first time the packaged app will be executed, the process.argv[1]
will be empty, so the server won't start. It will then execute the electron part (mainLocal in my case) and start the app over, but this time passing the argv
. Next time the app starts, it will start the server and stop the execution, so the app won't open again because spawn is never reached.
Huge thanks to Samuel.
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