I am working on a new project using Electron and ReactJS. The project works fine in development mode, but I am trying to create an installer for Windows but no matter what I try and what I find on Google nothing works. I just get a blank white screen.
Below is my pacakge.json
{
"name": "MyApp",
"description": "My App Description",
"version": "0.1.2",
"private": true,
"homepage": "./",
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@types/jest": "^26.0.14",
"@types/node": "^14.11.2",
"@types/react": "^16.9.50",
"@types/react-dom": "^16.9.8",
"bootstrap": "^4.5.2",
"electron-is-dev": "^1.2.0",
"electron-settings": "^4.0.2",
"electron-squirrel-startup": "^1.0.0",
"react": "^16.13.1",
"react-bootstrap": "^1.3.0",
"react-dom": "^16.13.1",
"react-icons": "^3.11.0",
"react-json-pretty": "^2.2.0",
"react-scripts": "3.4.3",
"react-tooltip": "^4.2.10",
"typescript": "^4.0.3"
},
"main": "src/electron-starter.js",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"electron-start": "set ELECTRON_START_URL=http://localhost:3000 && electron .",
"package-win": "electron-packager . --asar --out=release-builds --platform=win32 --arch=x64 --no-prune --ignore=/e2e --overwrite",
"create-installer-win": "node installers/windows/createInstaller.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"
]
},
"devDependencies": {
"electron": "^10.1.3",
"electron-packager": "^12.0.1",
"electron-winstaller": "^4.0.1",
"react-router-dom": "^5.2.0",
"react-toastify": "^6.0.8"
}
}
My electron-start.js script is below
const {electron, Menu, app, BrowserWindow} = require('electron');
// Module to control application life.
//const app = electron.app;
// Module to create native browser window.
//const BrowserWindow = electron.BrowserWindow;
const path = require('path');
const url = require('url');
if (require('electron-squirrel-startup')) app.quit()
// if first time install on windows, do not run application, rather
// let squirrel installer do its work
const setupEvents = require('../installers/setupEvents')
if (setupEvents.handleSquirrelEvent()) {
console.log("Squirrel event returned true");
process.exit()
//return;
}
console.log("Starting main program");
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;
/*const env = process.env.NODE_ENV;
let windowUrlBase = "";
if (env === "production")
{
windowUrlBase = "/";
}
else
{
windowUrlBase = 'http://localhost:3000';
}*/
let windowUrlBase = 'http://localhost:3000';
function returnMainWindow()
{
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
//preload: __dirname + '/preload.tsx'
}
});
//const env = process.env.NODE_ENV;
//console.log("Environment: " + env);
const isDev = require('electron-is-dev');
windowUrlBase = "";
console.log("Not electron dev");
console.log("dir name: " + __dirname);
const startUrl = process.env.ELECTRON_START_URL || url.format({
//pathname: path.join(__dirname, '/../build/index.html'),
pathname: path.join(__dirname, '../index.html'),
protocol: 'file:',
slashes: true,
webSecurity: false
});
mainWindow.loadURL(startUrl);
return mainWindow;
}
function createWindow() {
// Create the browser window.
mainWindow = returnMainWindow();
mainWindow.maximize();
// and load the index.html of the app.
// Open the DevTools.
//mainWindow.webContents.openDevTools();
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
setMainMenu();
}
function setMainMenu()
{
const template = [
{
label: 'File',
submenu: [
{
label: 'Exit',
accelerator: "ctrl+f4",
click() {
app.quit();
}
}
]
},
{
label: 'Edit',
submenu: [
{
label: 'Settings',
click() {
mainWindow.loadURL(windowUrlBase + "/settings");
}
}
]
},
{
label: 'Help',
submenu: [
{
label: 'Show Dev Console',
accelerator: "f11",
click() {
mainWindow.webContents.openDevTools();
}
}
]
}
];
Menu.setApplicationMenu(Menu.buildFromTemplate(template));
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
});
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
});
My create installer script is below
const createWindowsInstaller = require('electron-winstaller').createWindowsInstaller
const path = require('path')
getInstallerConfig()
.then(createWindowsInstaller)
.catch((error) => {
console.error(error.message || error)
process.exit(1)
})
function getInstallerConfig () {
console.log('creating windows installer')
const rootPath = path.join('./')
const outPath = path.join(rootPath, 'release-builds')
return Promise.resolve({
appDirectory: path.join(outPath, 'crash-catch-control-panel-win32-x64'),
authors: 'Boardies IT Solutions',
noMsi: true,
outputDirectory: path.join(outPath, 'windows-installer'),
exe: 'crash-catch-control-panel.exe',
setupExe: 'crash-catch-control-panel-installer.exe'
//setupIcon: path.join(rootPath, 'assets', 'images', 'logo.ico')
})
}
My setupEvents.js is below
const electron = require('electron')
const app = electron.app
module.exports = {
handleSquirrelEvent: function() {
if (process.argv.length === 1) {
return false;
}
const ChildProcess = require('child_process');
const path = require('path');
const appFolder = path.resolve(process.execPath, '..');
const rootAtomFolder = path.resolve(appFolder, '..');
const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'));
const exeName = path.basename(process.execPath);
const spawn = function(command, args) {
let spawnedProcess, error;
try {
spawnedProcess = ChildProcess.spawn(command, args, {detached: true});
} catch (error) {}
return spawnedProcess;
};
const spawnUpdate = function(args) {
return spawn(updateDotExe, args);
};
const squirrelEvent = process.argv[1];
switch (squirrelEvent) {
case '--squirrel-install':
case '--squirrel-updated':
// Optionally do things such as:
// - Add your .exe to the PATH
// - Write to the registry for things like file associations and
// explorer context menus
// Install desktop and start menu shortcuts
spawnUpdate(['--createShortcut', exeName]);
setTimeout(app.quit, 1000);
return true;
case '--squirrel-uninstall':
// Undo anything you did in the --squirrel-install and
// --squirrel-updated handlers
// Remove desktop and start menu shortcuts
spawnUpdate(['--removeShortcut', exeName]);
setTimeout(app.quit, 1000);
return true;
case '--squirrel-obsolete':
// This is called on the outgoing version of your app before
// we update to the new version - it's the opposite of
// --squirrel-updated
app.quit();
return true;
}
}
}
My App.js is below
import * as React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom'
import './Stylesheet.css'
import Dashboard from "./Components/Dashboard";
import Settings from "./Components/Settings";
import './ComponentStyles/BreadcrumbNav.css'
import 'react-toastify/dist/ReactToastify.min.css';
import { ToastContainer, toast } from 'react-toastify';
import CustomerDetails from "./Components/CustomerDetails";
toast.configure({
position: 'top-center',
hideProgressBar: true
});
function App() {
return (
<BrowserRouter>
<div>
<Switch>
<Route path="/" render={() => <Dashboard /> } exact />
<Route path="/customer-information/:customer_id" render={(props) => <CustomerDetails {...props} /> } exact />
<Route path="/settings" render={() => <Settings /> } exact />
</Switch>
</div>
</BrowserRouter>
);
}
export default App;
When I look at the chrome console when the app loads I see the following error:
Not allowed to load local resource: file:///C:/Users/Chris/AppData/Local/MyApp/app-0.1.2/resources/app.asar/index.html
As mentioned above the problem only happens when I launch the electron app when its installed. If I launch it as part of the Node dev server then it works perfectly fine.
from Creating an installer for Electron React JS app - reactJS component doesn't load when run after install
No comments:
Post a Comment