nextron
nextron copied to clipboard
Nextron app opens new instance each time a change is made in app files
How do I keep it from opening multiple instances when running it from dev mode? Like if I have a window open and I add a space to a string in an app file then it will open another instance of the app without closing the first one
You can close the ~~previous one like~~ one just opened:
if (app.requestSingleInstanceLock()) app.on('ready', setUp);
else app.quit();
Only problem I haven't figure out yet is how to have hot reload in that specific window
You can close the ~previous one like~ one just opened:
if (app.requestSingleInstanceLock()) app.on('ready', setUp); else app.quit();
Only problem I haven't figure out yet is how to have hot reload in that specific window
Thanks for responding! This should be added to the base app because it can get annoying during dev. That or have a setting to enable or disable it in a config
any ideas to close the previous window?
Hey @azwalzaman, nice to read you, if I understand well you would like to close all previous window cause each time you add a char in your files a new window is created without closing previous, right? If it's correct could you share to us your code where you create the window?
@alexis-piquet CC: @irg1008 @nekochan0122 @alexis-piquet
Sorry for late reply 🙇
Currently, nextron has --run-only
option, so if you have time could you try to use this one?
Thanks in advance,
{
"scripts": {
"dev": "nextron --run-only"
}
}
Reference: https://github.com/saltyshiomix/nextron/tree/v8.11.2#--run-only-default-undefined
@saltyshiomix this will not open a new window with every change in Electron, but is also useless for development, as we want hot-reloading. But just not having to deal with all the windows it opens after each hot-reload.
We overlooked the comment by @irg1008
TL;DR: It's a tricky one 😢. This post does not offer a solution, but an insight
We actually want this in general as our app should always enforce a single instance. When the code is implemented it does in fact resolve the issue of multiple instances opening during development and should also deliver the behavior we intend our packaged app to reflect. As they correctly mentioned it does not push updates to the background/main process though. What is described as "hot-reloading" might be misleading though, as opening a new instance also suggests that no hot-reloading takes place.
This is not pretty at all, since with a single instance one might "forget" that a change has taken place and wonder why changes are not applied. Restarting the development script manually is mandatory. It furthermore reasons why it is not a solution to enforce this mechanism in the development script of nextron as @azwalzaman suggested. Sorry, sadly it is not all that easy.
Conclusion:
- handling
app.requestSingleInstanceLock()
can prevent multiple main processes if handled correctly - Single instances still allows client/renderer to receive hot reloading
- Background/main process needs to be restarted to reflect changes
Task
- implement a development speciffic helper that will close the running app and open the new instance instead (investigation required)
Challenges
- figuring out a reasonable mechanism to enforce a new app to open only during development
- Initial testing did not offer a drop in solution to this problem
- Simply switching the logic depending on the development/producion flag will cause the app to always close
- instances seem to not know about changes, so closing the "previous" instance might be challenging or even impossible
Additional info
Electron offers an event to listen for a second instance. We might be able to use it to handle closing the existin instance. See the example below which aims to use the listener.
Warning: this does not seem to work as the second instance will be a zombie process. Every second save will spawn a new instance though, which does reflect changes, while only keeping one running process open. It will, nevertheless cause multiple zombie console windows open, therefore not achieving the intended behavior. Additional changes will then continue to spawn multiple instances of the console/main process and client/renderer, bringing us back to the inital problem of having multiplee open windows
Example:
app.on("second-instance", async () => {
if (isDevelopment) {
console.log("Development mode: force close app.");
app.quit();
}
});
For those, wondering what the mechanism of locking might look like, here's a code snippet including the relevant link to the documentation of electron:
// Obtain a lock to check if the app is locked (primary instance)
// If false, we close the app, as we want to prevent multiple instances of our app
// https://github.com/electron/electron/blob/v30.0.0-nightly.20240221/docs/api/app.md#apprequestsingleinstancelockadditionaldata
const gotTheLock = app.requestSingleInstanceLock();
if (gotTheLock) {
// Initialize the application by calling the main function.
// Upon completion, log to the console indicating the application has started.
main().then(() => {
logger.info("Application started successfully");
});
// Listen for the 'window-all-closed' event on the Electron app object.
// This event is emitted when all windows of the application have been closed.
// In response, quit the application to free up resources, adhering to typical desktop application
// behavior.
app.on("window-all-closed", () => {
app.quit();
});
} else {
// The app is locked, so we force quit the new instance
console.log("App is locked by another instance. Closing app");
app.quit();
}