I have a React Electron application that currently builds and runs off the built html file of my react app. For ease of hot fixes/updates (this is an internal tool), id like to have the build of the electron app use the entire react app and bundle in those files and run the react server. Is there an easy way to do that?
Here is Package.Json
"name": "testapp",
"version": "1.0.1",
"author": "author",
"description": "testapp client application.",
"homepage": ".",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.3.3",
"concurrently": "^8.2.2",
"cross-env": "^7.0.3",
"react": "^18.2.0",
"react-bootstrap": "^2.10.2",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.3",
"react-scripts": "5.0.1",
"wait-on": "^7.2.0",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"electron": "^30.0.9"
},
"scripts": {
"start-react": "react-scripts start",
"build-react": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"start-electron": "electron .",
"start": "concurrently "cross-env BROWSER=none npm run start-react" "wait-on http://127.0.0.1:3000 && npm run start-electron"",
"build": "npm run build-react && electron-builder -w -c.extraMetadata.main=build/electron.js"
},
"eslintConfig": {
"extends": [
"react-app"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"electron": "electron .",
"main": "public/electron.js",
"build": {
"extends": null,
"appId": "com.testapp.app",
"productName": "testapp",
"files": [
"public/**/*",
"dist/**/*",
"build/**/*",
"node_modules/**/*",
"package.json"
],
"directories": {
"buildResources": "public",
"output": "build"
},
"win": {
"target": "nsis",
"icon": "testappLogo.png"
},
"extraResources": {
"filter": ["./config.json"]
}
}
}
Electron.js:
const path = require('path');
const fs = require('fs');
const isPackaged = app.isPackaged;
//force dark mode electron ui
nativeTheme.themeSource = "dark"
function createWindow () {
const win = new BrowserWindow({
width: 1500,
height: 600,
webPreferences: {
nodeIntegration: true,
enableRemoteModule:true,
preload: path.join(__dirname, 'preload.js'),
},
title:"TestApp"
})
//Open devTools in dev
if(!isPackaged){
win.webContents.openDevTools("detach", false, "DevTools");
}
//load the index.html from a url
win.loadURL(
!isPackaged
? 'http://localhost:3000'
:
`file://${path.join(__dirname, '../build/index.html')}`
);
}
function helpWindow(){
const helpWin = new BrowserWindow({
width: 800,
height: 500,
webPreferences: {
nodeIntegration: true,
enableRemoteModule:true,
},
title:"About This Version"
})
//load the index.html from a url
helpWin.loadURL(`file://${path.join(__dirname, '../build/help.html')}`);
}
const menu = [
{
label: 'App',
submenu: [
{ label: 'Quit', role: 'quit'},
]
},
{
label: 'WebPage',
submenu: [
{ label: 'DevTools', role: 'toggleDevTools', accelerator: 'f12'},
{ label: 'Reload', role: 'reload', accelerator: 'f5'},
{ label: 'ForceReload', role: 'forceReload', accelerator: 'ctrl+f5'}
]
},
{
label: 'About This Version',
click: helpWindow,
}
]
app.whenReady().then(async() => {
createWindow();
const electronMenu = Menu.buildFromTemplate(menu);
Menu.setApplicationMenu(electronMenu);
app.on('activate',async () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
});
ipcMain.handle('get-config', async (event) => {
try {
if(!isPackaged){
return { 'apiUrl' : 'http://localhost:2223'}
} else {
const configPath = path.join(process.resourcesPath, 'config.json');
const data = fs.readFileSync(configPath, 'utf-8');
return JSON.parse(data);
}
} catch (err) {
console.error("Failed to load config", err);
return { error: 'Failed to load config file' };
}
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})