Electron renderer not invoked - javascript

I'm learning electron, took electron-quick-start and made certain modifications to index.html, main.js and renderer.js following the tutorial at
https://blog.logrocket.com/handling-interprocess-communications-in-electron-applications-like-a-pro/
index.html
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
</script>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>Electron-Process-Comm</title>
<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
</head>
<body>
<h2 id="mainWindowTitle">I am the main window</h2>
<button id="sendSyncMsgBtn">Ping Main Process</button>
<p id="syncReply">Chilling for response</p>
<!-- You can also require other files to run in this process -->
<script src="./renderer.js"></script>
</body>
</html>
main.js
// Modules to control application life and create native browser window
const {app, BrowserWindow} = require('electron')
const path = require('path')
const ipcMain = require('electron').ipcMain
console.log('Hello')
ipcMain.on('sync-message', (event, arg) => {
console.log('IPCMain')
event.returnValue = 'Message Recieved!'
})
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
renderer.js
const electron = require('electron')
const ipc = electron.ipcRenderer
const syncMsgBtn = document.querySelector('#sendSyncMsgBtn')
console.log('Hello renderer')
syncMsgBtn.addEventListener('click', () => {
console.log('Renderer')
const reply = ipc.sendSync('sync-message', 'Sent from main Window')
const message = `Synchronous message reply: ${reply}`
document.querySelector('#syncReply').innerHTML = message
})
const asyncMsgBtn = document.querySelector('#sendAsyncMsgBtn')
asyncMsgBtn.addEventListener('click', () => {
ipc.send('async-message', 'Async message baby')
})
Now, though renderer.js is included in the index.html it is never invoked. The console log doesn't appear and the button click doesn;t respond. Can somebody tell me what i'm doing wrong ?

The code looks fine and should be executed when running. You might be looking at the wrong console? The log statements should appear in the console of the renderer window. To open the Developer Tools, you can press Cmd + Opt + I (macOS) and Ctrl + Shift + I (Windows).
You can find more information about debugging Electron applications in their documentation and the Developer Tools in Chrome's documentation.

Related

Preload Script not runnning/working properly with Electron

I've been trying to get a preload script to run on my Electron app but it appears to either not be running at all or just not working properly.
I currently have a main file, a preload file, a render file, and a html. I'm just trying to do the stuff from the Electron tutorial on using preload files, so right now my code is something like this:
// main.js
const {app, BrowserWindow, ipcMain, Menu} = require('electron');
const url = require('url');
const path = require('path');
let mainWindow;
const createWindow = () => {
// Create a window
mainWindow = new BrowserWindow({
show: false,
autoHideMenuBar: true,
webPreferences: ({
preload: path.join(__dirname, 'scripts', 'preload.js'),
nodeIntegration: true,
}),
});
mainWindow.maximize();
mainWindow.show();
// Load HTML into window
mainWindow.loadFile('index.html');
// Open Dev Tools
// mainWindow.webContents.openDevTools();
console.log(versions);
}
// preload.js
const {contextBridge} = require('electron');
contextBridge.exposeInMainWorld('versions', {
node: () => process.version.node,
chrome: () => process.version.chrome,
electron: () => process.version.electron,
});
Index.html:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./css/style.css">
<title>Test</title>
</head>
<body>
<h1>Test</h1>
<p id="info"></p>
<script>window.$ = window.jQuery = require('jquery');</script>
<script src="render.js"></script>
</body>
// render.js
const information = document.getElementById('info');
information.innerText = `This app is using Chrome (v${versions.chrome()}),
Node.js (v${versions.node()}), and Electron (v
${versions.electron()})`
Currently my output on the HTML from render.js is "This app is using Chrome (vundefined),Node.js (vundefined), and Electron (vundefined)" and my console.log line in main.js throws up a ReferenceError stating "versions is not defined". Anybody able to shine some light on how I could fix this? Thanks in advance.
I think you made a typo:
In your preload script
contextBridge.exposeInMainWorld('versions', {
node: () => process.version.node,
chrome: () => process.version.chrome,
electron: () => process.version.electron,
});
Should be (add a "s" to process.version
contextBridge.exposeInMainWorld('versions', {
node: () => **process.versions.node,
chrome: () => **process.versions.chrome,
electron: () => **process.versions.electron,
});
Can have a look to the docs:
https://www.electronjs.org/docs/latest/api/process

Electron shows blank window

My HTML file isn't loading at the tutorial says it would've. This is what I have. Yes, I've tried doing all sorts of funky stuff involving paths and it doesn't fix the issue.
main.js
const { app, BrowserWindow } = require('electron');
const path = require("path");
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile("index.html")
}
app.whenReady().then(() => {
createWindow()
})
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</body>
</html>
You might have to change your JavaScript code to have a full path to the HTML file.
Try with the code below, it will configure Electron. In the event listening, it is creating a new BrowserWindow with no configuration (although you can add it if you like). Then, it is loading the full path to the HTML file.
const electron = require("electron");
const {
app,
BrowserWindow
} = electron;
app.on("ready", () => {
const mainWindow = new BrowserWindow({});
mainWindow.loadURL(`file://${__dirname}\\index.html`);
});

How do I make button close Electron-JS app?

Code:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<link rel="stylesheet" type="text/css" href="index.css">
<title>Youtify</title>
</head>
<body>
<div id = "leftBar"></div>
<div id = "rightBar"></div>
<div id = "bottomBar"><hr></div>
<div id = "toolButtons">
<div id ="closeBtn"><a data-text="✖"></a></div>
<div id="maxBtn"><a data-text="❐" ></a></div>
<div id="minBtn"><a data-text="─" ></a></div>
</div>
<script src="./renderer.js"></script>
</body>
</html>
main.js
const {app, BrowserWindow, ipcMain} = require('electron') const path = require('path')
function createWindow () { const mainWindow = new BrowserWindow({
width: 800,
height: 600,
frame: false, })
mainWindow.loadFile('index.html') }
app.whenReady().then(() => { createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow() }) })
renderer.js
// close app
function closeApp(e) {
e.preventDefault();
app.quit();
}
document.getElementById("closeBtn").addEventListener("click", closeApp);
What I want is to click on the button with the id "closeBtn" to close the app, I was looking for it, but I just can't make it working.
Can anyone please help?
Try using ipcRenderer to send the close command to main.js
In your main.js:
ipcMain.on('close', () => {
app.quit()
})
Then, in your renderer.js:
const ipc = require('electron').ipcRenderer
// close app
function closeApp(e) {
e.preventDefault()
ipc.send('close')
}
document.getElementById("closeBtn").addEventListener("click", closeApp);

How to enable nodeintegration in electron webview?

I build an app with Electron an i try to use a webview to display a file loaded from my disk and i need nodeintegration in the webview. Although it is documented in the Electron Documentation here i can`t get it working.
I created a test project with the main.js file, which creates a BrowserWindow, where i load my index.html and index.js files. The index.js file creates a webview with my file loaded and the file is webview.html with webview.js. I call require in webview.js and i can see in the DevTools, that it is giving the error
Uncaught ReferenceError: require is not defined
at webview.js:2
Here are my testfiles, what am i missing or got this feature removed?
I am using Electron ^12.0.2
main.js
const { app, BrowserWindow, BrowserView } = require('electron')
function createWindow () {
let win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
webviewTag: true,
nodeIntegrationInWorker: true,
nodeIntegrationInSubFrames: true
}
})
win.loadFile('index.html')
return win;
}
app.whenReady().then(() => {
let win = createWindow();
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<div class="root">
</div>
<script src="index.js" charset="utf-8"></script>
</body>
</html>
index.js
function createWebview(id, url) {
//creates a webview with the id of the tab and the url loaded
let webview = document.createElement("webview");
webview.setAttribute("id", id);
webview.setAttribute("src", url);
webview.setAttribute("nodeintegration", "");
webview.setAttribute("preload", "./pre.js")
webview.addEventListener('dom-ready', () => {
webview.openDevTools();
});
console.log(webview);
return webview;
}
document.querySelector(".root").appendChild(createWebview("web", `file://${__dirname}/webview.html`));
webview.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
test
<script src="webview.js" charset="utf-8"></script>
</body>
</html>
webview.js
console.log("test");
//a require to test the functionality
const { app, BrowserWindow, ipcMain, Menu, MenuItem } = require('electron');
Edit 1: The preload script is empty.
After thinking much more i came to the solution, that if the webview is similar to the BrowserWindow, then i need to disable contextIsolation in the webPreferences object of the webview. This is definitely something that needs to be added to electron documenten.
I change my index.js file like this
function createWebview(id, url) {
//creates a webview with the id of the tab and the url loaded
let webview = document.createElement("webview");
webview.setAttribute("id", id);
webview.setAttribute("src", url);
webview.setAttribute("nodeintegration", "");
webview.setAttribute("webpreferences", "contextIsolation=false");
webview.addEventListener('dom-ready', () => {
webview.openDevTools();
});
console.log(webview);
return webview;
}
document.querySelector(".root").appendChild(createWebview("web", `file://${__dirname}/webview.html`));
Just add below two attributes in webPreference object to enable nodeIntegration in all js file which contains webView
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
nativeWindowOpen: true,
enableRemoteModule: true,
sandbox:false,
nodeIntegrationInSubFrames:true, //for subContent nodeIntegration Enable
webviewTag:true //for webView
}
don't use webview is not good idea to show external content using webView
it affects performance.!
See docs about webView below

My app doesn't close on button, electron.js

I have this electron.js app and I would like the application to close when I click on the text with class closer. Here is my code:
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="content">
<h1>Hello</h1>
<h1 class="closer">UUUU</h1>
</div>
<script src="./renderer.js"></script>
<script src="./closer.js"></script>
</body>
</html>
main.js initialization electron
const {app, BrowserWindow} = require('electron')
const path = require('path')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 1200,
height: 600,
backgroundColor: "red",
frame: false,
webPreferences: {
nodeIntegration: true,
preload: path.join(__dirname, 'preload.js')
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// mainWindow.webContents.openDevTools()
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
closer.js
const { app } = require('electron');
const babi = function(){
const bubu = document.querySelector('.closer');
function bubub(){
bubu.innerHTML = "aganim";
app.quit();
}
bubu.addEventListener('click', bubub);
}
babi();
My problem is that clicking the button, doesn't work. What should I do?
[...bubu].forEach(bubu =>
bubu.addEventListener("click", bubuClose())
);
function bubuClose() {
bubu.innerHTML = "aganim";
window.close();
};
I think you can do it with a loop like this.

Categories