Outsource functionality from main.js - javascript

I've started building an electron application from scratch. So far I can modify the mainWindow by inserting all the logic in main.js, but I'd like to keep the logic in separate files. Unfortunatly I fail to import them correctly, so help would be nice..
// main.js
const { app, BrowserWindow, Menu, dialog } = require('electron');
const fs = require('fs');
const { test } = require('./test'); // test module to be imported
let win;
function createWindow() {
win = new BrowserWindow({
icon: `file://${__dirname}/dist/text-editor/favicon.ico`,
webPreferences: {
nodeIntegration: true
}
});
win.maximize();
win.loadURL(`file://${__dirname}/dist/text-editor/index.html`);
win.webContents.openDevTools();
//menu bar
const template = getTemplate();
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
win.on('closed', function () {
win = null;
});
console.log(test.getName()); // throws error
}
// create window on electron init
app.on('ready', createWindow);
// quit when all windows are closed
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', function () {
if (win === null) {
createWindow();
}
});
function getTemplate() {...} // for example move this method to new file
// test.js
const getName = () => {
return "Tom";
};
module.exports.getName = getName;
Running this code with ng build --prod && electron . throws:
Cannot read property 'getName' of undefined.
Thanks in advance ;)

Please import your js as const test = require('./test') and then use test.getName() in your main js file. when calling const {test} is trying to import the test object in the at relevant file . You can read more about that from this answer

Related

My Electron app after packaging doesn't launch

hello guys so basically after packaging my app with multiple packagers it still doesnt want to load the window when i open my .exe file :/
const PHPServer = require('php-server-manager');
const { app, Menu, shell, ipcMain } = require('electron');
const config = require('config')
const path = require('path')
const MainWindow = require('./MainWindow')
let mainWindow;
process.env.NODE_ENV = 'production'
shell.showItemInFolder('fullPath')
const isDev = process.env.NODE_ENV !== 'production' ? true : false
const server = new PHPServer({
php: "foundation/php/php.exe", // <==== ADDED
port: 8000,
directory: path.resolve(__dirname)+'/source',
stdio: 'inherit',
directives: {
display_errors: 1,
expose_php: 1
},
config: `${__dirname}foundation/php/php.ini`
});
function createWindow() {
server.run();
mainWindow = new MainWindow('http://'+server.host+':'+server.port+'/', isDev)
mainWindow.on('closed',function(){
mainWindow = null;
})
}
// Close App
ipcMain.on('close-me', (evt, arg) => {
app.quit()
})
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') {
// PHP SERVER QUIT
server.close();
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()
}
})
//app.disableHardwareAcceleration()
app.commandLine.appendSwitch('force_high_performance_gpu')
app.allowRendererProcessReuse = true
this is my main.js and im using PHP in this electron project
also note that i use electron-forge for packaging
when i run npm start , the window show up perfectly but whenever i package my tool and then try to open the exe file it seems like nothing show up only a small icon of the app in the explorer bar , pretty weird since there is no error in my code ,
anyone has an answer ?

Uncaught TypeError: Cannot destructure property 'dialog' of 'require(...).remote' as it is undefined even thought enable remote modules set to true

I am trying to open a dialog box in my electron app but when I Try importing it in my app.js the error in the title shows up even thought 'enableRemoteModule' is set to true .
I am trying to open a dialog box in my electron app but when I Try importing it in my app.js the error in the title shows up even thought 'enableRemoteModule' is set to true .
app.js
const { dialog } = require("electron").remote;
const OpenBookBtn = document.getElementById("OpenBookBtn")
const viewerElement = document.getElementById('viewer')
const CloseBookBtn = document.getElementById("CloseBookBtn")
WebViewer({
path:'../public/lib',
},viewerElement).then(instance =>{
instance.setTheme("dark");
})
viewerElement.style.display = 'none'
OpenBookBtn.addEventListener('click',()=>{
const file = dialog.showOpenDialog();
viewerElement.style.display = "block"
})
CloseBookBtn.addEventListener('click',(event)=>{
viewerElement.style.display = 'none'
})
index.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) { // eslint-disable-line global-require
app.quit();
}
const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
contextIsolation: false,
},
width: 800,
height: 600,
});
// and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, 'index.html'));
// Open the DevTools.
mainWindow.webContents.openDevTools();
};
// 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, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// 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 (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.
First install the remote module using
> npm install #electron/remote
In the new versions of electron, you have to include remote as
const remote = require('#electron/remote');
const { dialog } = remote;
And in your index.js file add the following
const remoteMain = require('#electron/remote/main');
remoteMain.initialize();
Also, after creating the mainWindow object
remoteMain.enable(mainWindow.webContents)

`loadURL` in Electron has error "window.require is not a function" only this website

NOTE: Electron 17.0.1
I'm so confuse about to use the win.loadURL function in Electron.
For main purpose, to create a dark theme for chat application.
I want to loadURL in Electron and inject CSS to change to dark theme.
BUT when I use loadURL and then run Electron app.
It will show an error "window.require is not a function"
and "Uncaught TypeError: Cannot read properties of undefined (reading 'instance')"
here is my code:
// main.js
const { app, BrowserWindow } = require("electron");
const path = require("path");
function createWindow() {
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
},
});
win.webContents.openDevTools();
win.loadURL("https://seatalkweb.com/");
}
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
// preload.js
window.addEventListener("DOMContentLoaded", () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector);
if (element) element.innerText = text;
};
for (const type of ["chrome", "node", "electron"]) {
replaceText(`${type}-version`, process.versions[type]);
}
});
and this is an error:
I do not know why it has an error only this website when open in electron? (no problem if open in chrome)
this website is https://seatalkweb.com/
and it fine if I use other URL instead (such as google.com, facebook.com, etc.)
How can I fix it ?
and could somebody can explain me about this problem ?
Seems weird like a require is called is your page but it's maybe an Electron call du to the LoadUrl... If it's a require problem you may need to activate the Node integration..
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
nodeIntegration: true
},
});
If it's not from Electron Node integration, then in may be a problem in your web page script.

Error after updating electron and changin nodeIntegration to true

I recently went back to an old project and updated my electron version. I found online that electron now requires you to add in nodeIntegration: true in order to be able to import electron in your render process. I added this in as seen below, however, I am getting the following error after doing so and am unsure how to resolve this.
// Module Imports
const {app,BrowserWindow,dialog,ipcMain,remote} = require('electron')
var handlers = require('./routelist.js');
var dns = require('dns').promises;
var path = require('path');
var Connection = require('tedious').Connection;
var sql = require('sequelize');
var axios = require('axios');
let win
function createWindow () {
win = new BrowserWindow({webPreferences: {nodeIntegration: true}, width: 1730, height: 900, frame: false})
win.loadFile('./render/index.html')
win.webContents.openDevTools()
win.on('closed', () => {
win = null
})
}
app.on('ready', function() {
createWindow()
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null) {
createWindow()
}
})
Error:
Uncaught (in promise) TypeError [ERR_INVALID_ARG_TYPE]: The "id" argument must be of type string. Received type object
at validateString (internal/validators.js:112)
at Module.require (internal/modules/cjs/loader.js:768)
at require (internal/modules/cjs/helpers.js:68)
at vendor-bundle.js:7033
at new Promise (<anonymous>)
at createLoader (vendor-bundle.js:7032)
Let me know if I can provide further information.
electron now requires you to add in nodeIntegration: true in order to be able to import electron in your render process
You cannot directly use electron in a renderer process, use electron.remote:
const { remote } = require('electron');
const window = new remote.BrowserWindow({ width: 800, height: 600 });
See https://electronjs.org/docs/api/remote
After Using the chrome debugger for a really long time trying to locate when this error is happening it isn't related to electron in the slightest. The vendor bundle I am using is passing in an incorrect value for one of it's dependencies
Thanks to everyone for your time.

Electron - Close initial window but keep child open

I am coding an electron app which is supposed to load a splash screen, and then open a new window. Afterwards the splash screen should be closed.
However I am not able to do that. In my index.js, the startup script, I have the following code:
const { app, BrowserWindow } = require("electron");
app.on("ready", () => {
let win = new BrowserWindow({ /*...*/ });
win.loadURL(`file://${__dirname}/splash/splash.html`);
win.on("ready-to-show", () => { win.show(); });
win.on("closed", () => { app.quit(); });
});
In splash.html I load the splash.js by using
<script>require("./splash");</script>
And in splash.js I tried the following code:
const remote = require("electron").remote;
let tWin = remote.getCurrentWindow();
let next = function(){
let win = new remote.BrowserWindow({ /*...*/ });
win.loadURL(`file://${__dirname}/main/main.html`);
win.on("ready-to-show", () => { win.show(); });
win.on("closed", () => { app.quit(); });
tWin.close();
// I could just use win.hide(); here instead
// of tWin.close(); but that can't really be the right way.
};
The function next() gets called after a timeout. The problem is, if called, the main window shows up for a second but both, slpash and main close instantly.
I tried to fix that by commenting out
win.on("closed", () => { app.quit(); });
in my index.js. But that led to the following error:
Attempting to call a function in a renderer window that has been closed or released.
Uncaught Exception:
Error: Attempting to call a function in a renderer window that has been closed or released. Function provided here: splash.js:38:9.
at BrowserWindow.callIntoRenderer (/usr/lib/node_modules/electron-prebuilt/dist/resources/electron.asar/browser/rpc-server.js:199:19)
at emitOne (events.js:96:13)
at BrowserWindow.emit (events.js:188:7)
Does anyone have an idea on how to prevent the newly created window from closing?
I usually use a diferent approach. Here's how a use do it:
create global var reference for the main window and the splash window, if not it will be self closed by the garbage collector.
load 'splash' browserwindow
on 'show' event I call a function to load 'main' window
on main window 'dom-ready', I close 'splash' and show 'main'
Here's one example of my main.js electron code, feel free to ask:
'use strict';
//generic modules
const { app, BrowserWindow, Menu } = require('electron');
const path = require('path')
const url = require('url')
const config = require('./config'); // => 1: archivo de configuracion
const fileToLoad = config.files.current ? config.files.current : config.files.raw;
const jsonData = require(fileToLoad); // => 2: archivo de datos (json)
const pug = require('electron-pug')({ pretty: true }, jsonData); // => 3: pasamos datos ya tratados a plantillas pug/jade
// 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 win, loading
app.mainWindow = win;
function initApp() {
showLoading(initPresentation)
}
function showLoading(callback) {
loading = new BrowserWindow({ show: false, frame: false })
loading.once('show', callback);
loading.loadURL(url.format({
pathname: path.join(__dirname, '/src/pages/loading.html'),
protocol: 'file:',
slashes: true
}))
loading.show();
}
function initPresentation() {
win = new BrowserWindow({
width: 1280,
height: 920,
show: false,
webPreferences: {
experimentalFeatures: true
}
})
win.webContents.once('dom-ready', () => {
console.log("main loaded!!")
win.setMenu(null);
win.show();
loading.hide();
loading.close();
})
// Emitted when the window is closed.
win.on('closed', () => {
// 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.
win = null
})
win.loadURL(url.format({
//pathname: path.join(__dirname, '/src/pages/home.pug'),
pathname: path.join(__dirname, '/lab/pug/index.pug'),
protocol: 'file:',
slashes: true
}))
win.webContents.openDevTools() // Open the DevTools.
}
// 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', initApp)
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS 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', () => {
// On macOS 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 (win === null) {
initApp()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.*/

Categories

Resources