Reputation: 314
I am using Electron with React, and works perfectly, but the problem that I'm facing I need to know how I can include a nodejs express server to my reactjs project so when I run the electron-builder and generate the .exe file I need the server to be included and to run automatically when running the app.exe.
I tried to install the folder of the server as a dependency by running npm install ./server
, and I require it by adding require('server')
from the electron.js
, but when I install the .exe of the app and try to run it the server is running perfectly and the api calls are sent correctly, but the async functions in the server are not working.
this is my electron.js file created in the public folder:
const { app, BrowserWindow } = require('electron');
const isDev = require('electron-is-dev');
const path = require('path');
const find = require('find-process');
require('server');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
show: false,
icon: `file://${path.join(__dirname, '/icon.png')}`
});
const startURL = isDev ? 'http://localhost:3333' : `file://${path.join(__dirname, '../build/index.html')}`;
mainWindow.loadURL(startURL);
mainWindow.setMenu(null)
mainWindow.webContents.openDevTools();
mainWindow.once('ready-to-show', () => mainWindow.show());
mainWindow.on('closed', () => {
mainWindow = null;
});
}
app.on('ready', createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (mainWindow === null) {
createWindow();
}
});
app.on('before-quit', (e) => {
find('port', 3333)
.then(function (list) {
if (list[0] != null) {
console.log('---kill---:', list[0].pid);
process.kill(list[0].pid, 'SIGHUP');
}
})
.catch((e) => {
console.log('---error---', e.stack || e);
});
});
this is my nodejs login api call function:
exports.login = async (req, res) => {
try {
const { email, password } = req.body;
console.log(req.body)
if (!email || !password)
throw new Error(`Please provide email and password`);
const pool = await getConnection();
// Take care about the '' in email(VARCHAR)
const testpass = await bcrypt.hash(password, HASH_SALT);
console.log("testpass ", testpass);
console.log("DB_USER_TABLE ", process.env.DB_USER_TABLE);
if (!pool) {
throw new Error(`Pool not valid`);
}
const result = await pool
.request()
.query(
`SELECT * FROM ${process.env.DB_USER_TABLE} WHERE email = '${email}';`
);
console.log(result)
const user = result.recordset[0];
console.log(user)
if (!user || !(await correctPassword(password, user.password)))
throw new Error('WRONG_CREDENTIALS');
// 401: Error for user not found
createSendToken(user, res);
} catch (err) {
console.log(`⛔⛔⛔ LOGIN: ${err.message}`);
res.status(401).json({
status: 'fail',
message: err.message,
});
}
};
when I try to login I got that error:
the pool object is empty which means it doesn't wait for the function getConnection to be executed (in development mode the function works), here is the getConnection function:
async function getConnection() {
try {
const pool = await sql.connect(sqlSettings);
if (!pool) throw new Error('Error trying to connect');
return pool;
} catch (err) {
console.log(`⛔⛔⛔: ${err.message}`);
}
}
I tried to replace the async and await in the getConnection function and use instead .then()
but I never get a response to the front end when I do that, in postman it keeps loading and waiting for response.
I don't know what is really the problem, even if it's working perfectly if I run the project in dev mode with npm start
Any suggestions how I can solve that? and any advices about the good approach for building a management desktop app from reactjs with a database to store the data?
Upvotes: 6
Views: 925
Reputation: 2019
One thing that stands out to me is that it seems like you are attempting to run the server on the same process as the electron app. This can cause some unexpected behavior. Since you want to package everything together, one option would be to use the nodejs standard child process api to create another process that runs the server instead.
To do so simply use the execFile
method:
const { execFile } = require('node:child_process');
// You can remove the `require('server')`
// and simply pass the path to the index file to be run.
const child = await execFile('node', 'PATH TO FILE');
// You have the `child` object to access the `stdout` and `stdin`
// as well as killing the process when the app is terminated.
Now the electron app and the server will be running on separate processes and wont interfere with each other.
Upvotes: 0