This question already has answers here:
Unable to use Node.js APIs in renderer process
(2 answers)
Closed 1 year ago.
I'm new to Electron, and I've really been struggling with getting it to work. I'm experiencing behavior I cannot explain, so here's a sum:
I cannot get the communication between Electron and the html to work
"Uncaught ReferenceError: require is not defined" inside the website, even though I have nodeIntegration:true
File Tree:
./
index.html
index.js
package-lock.json
package.json
node_modules/
index.js:
const electron = require("electron");
const Ffmpeg = require("fluent-ffmpeg");
const CmdExec = require('child_process');
const {
app,
BrowserWindow,
ipcMain
} = electron;
function createWindow() {
//If I put the main window ini into here, and then call app.on("ready", createWindow()); app says
//"Cant create window before ready", even though I just moved the funcion from inside ready to here..
}
app.on('ready', () => {
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
});
mainWindow.loadURL(`${__dirname}/index.html`);
});
ipcMain.on("video:submit", (event, path) =>{
CmdExec.exec("echo hello", (value)=>{console.log(value)});
});
html:
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="">
</head>
<body>
<h1>WELCOME!</h1>
<script src="" async defer></script>
<form action="">
<div>
<br>
<label for=""></label>
<input type="file" accept="video/*" name="" id="">
</div>
<button type="submit">get info</button>
</form>
<script>
const electron = require("electron");
electron.send('perform-action', args);
document.querySelector("form").addEventListener("submit", (event) => {
event.preventDefault();
const {path} = document.querySelector("input").files[0];
window.api.send("video:submit", path);
});
//Tried multiple methos Ive found on stackoverflow,, dont think I implemented them right
//though
</script>
</body>
</html>
package.json:
{
"name": "media_encoder",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"electron": "electron ."
},
"author": "",
"license": "ISC",
"dependencies": {
"electron": "^12.0.0"
}
}
Electron 12 is now defaulting contextIsolation to true, which disables Node (here are the release notes; and here's the PR).
Here's a discussion of this change. nodeIntegration for what it's worth is going to be removed in a future Electron version.
The easiest way to fix this is to simply disable context isolation:
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
That being said, you might want to consider keeping contextIsolation enabled for security reasons. See this document explaining why this feature bolsters the security of your application.
Related
I'm hosting a Vue.js app on a Node.js Express app which works perfectly when running locally. When I upload it to cPanel, it only loads the index.html leaving me with a blank page and several 404 errors for all the "missing" files which are sitting next to it.
NODE: app.js
const express = require("express");
const cors = require("cors");
const path = __dirname + '/client';
const app = express();
app.use('/', express.static(path));
app.use(cors({ origin: '*' }));
app.get('/test', function (req, res) {
res.send("API TEST!");
});
// set port, listen for requests
const PORT = 8080;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
NODE: package.json
{
"name": "basic_node_app",
"version": "1.0.0",
"description": "A Basic Node App to serve something.",
"main": "app.js",
"author": "",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.17.1"
}
}
VUE: index.html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="/favicon.ico">
<title>basic_vue_app</title>
<link href="/js/app.62f5dd50.js" rel="preload" as="script">
<link href="/js/chunk-vendors.2b964eb5.js" rel="preload" as="script">
</head>
<body><noscript><strong>We're sorry but basic_vue_app doesn't work properly without JavaScript enabled. Please enable it
to continue.</strong></noscript>
<div id="app"></div>
<script src="/js/chunk-vendors.2b964eb5.js"></script>
<script src="/js/app.62f5dd50.js"></script>
</body>
</html>
VUE: App.vue
<template>
<div>
<label>THIS IS A GOOD TEST</label>
<label>API WORKS -> {{ apiresult }}</label>
</div>
</template>
<script>
import Axios from "axios";
export default {
name: "App",
data() {
return {
apiresult: "",
};
},
mounted() {
Axios.get("/test").then((res) => {
this.apiresult = res.data;
});
},
};
</script>
<style>
</style>
VUE: dist folder
JS folder
app.[id].js
app.[id].js.map
chunck-vendors.[id].js
chunck-vendors.[id].js.map
favicon.ico
index.html
on my cPanel, this is my structure:
image1
I'm running the node app like this:
image2
Finally, my problem. When I run it locally I get this on my browser:
image3
But when I deploy it and run it on cPanel I get:
image4
Thanks in advance for all your help.
Best regards,
First of all, I know that this is a question only a beginner would ask, but after going through more than 50 different solutions, uninstalling npm and installing yarn I have to ask this incredible dumb question.
Why doesnt this work?
I want to implement a simple titlebar using ElectronJS, the problem that I have is that the buttons (Close / Minimize / Maximize) do not work. The errors that I receive are the following:
The minimize error: titlebar.js:16 Uncaught TypeError: Cannot read property 'BrowserWindow' of undefined at HTMLButtonElement.maximizeApp (titlebar.js:16)
The maximize error: titlebar.js:16 Uncaught TypeError: Cannot read property 'BrowserWindow' of undefined at HTMLButtonElement.maximizeApp (titlebar.js:16)
The quit error: titlebar.js:21 Uncaught TypeError: Cannot read property 'getCurrentWindow' of undefined at HTMLButtonElement.quitApp (titlebar.js:21)
The JavaScript file that I use to control this is called titlebar.js. This is it:
const remote_v = require("electron").remote;
var minimize_v = document.getElementById("minimize");
var maximize_v = document.getElementById("maximize");
var quit_v = document.getElementById("quit");
minimize_v.addEventListener("click",minimizeApp);
maximize_v.addEventListener("click",maximizeApp);
quit_v.addEventListener("click",quitApp);
function minimizeApp(){
remote_v.BrowserWindow.getFocusedWindow().minimize();
}
function maximizeApp(){
remote_v.BrowserWindow.getFocusedWindow().maximize();
}
function quitApp(){
remote_v.getCurrentWindow().close();
}
Since many of the fixes for other problems like this is in the render process, this is the HTML File:
<!DOCTYPE html>
<head>
<title>Visionizer</title>
<link rel="stylesheet" href="css/editor.css">
<link rel="stylesheet" href="css/titlebar.css" >
</head>
<body>
<div class="container">
<div class="titlebar titlebarStyle">
<div class="windowTitle"> Visionizer </div>
<div class="windowControls windowControlsStyle">
<button id="minimize">-</button>
<button id="maximize">[]</button>
<button id="quit">x</button>
</div>
</div>
<div class="editorScreen">
</div>
</div>
<script src="js/titlebar.js"></script>
</body>
</html>
The weird thing about this is that, after much trying, I decided to copy the code from the tutorial from github, I thought that there may have been an error in my code that I was too dumb to see. It still didn't run. I uninstalled the package with npm and installed it with yarn using yarn global add electron#latest since some people suggested this.
I do not know whether this is important at all, but I will also copy my code from the main.js-file below since I want to be sure that I included everything:
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 900,
height: 800,
minHeight: 650,
minWidth: 600,
frame: false,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('editor.html')
win.webContents.openDevTools()
}
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
And here is the package.json file:
{
"dependencies": {
"electron": "^11.0.2"
},
"name": "*******",
"version": "1.0.0",
"description": "**********",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"author": "************",
"license": "MIT"
}
Some questions on the internet were answered by saying that the project was started wrongly, I followed their advice, I start my projects using the yarn start command
Thank you for reading through this.
It looks like your remote module is undefined.
You'd want to set enableRemoteModule: true in your main window's webPreferences, or better yet, scrap remote altogether and do these operations from the main process.
The remote module was disabled in Electron 10.
I do not get the desired output when running the following electron app i.e alert box containing pwd as output. However, the commented line inside index.html seems to work fine. The developer console of the chromium window says "Uncaught ReferenceError: __dirname is not defined at HTMLButtonElement.<anonymous>". This snippet is taken verbatim(except the commented line) from the book "Electron in action" by Steve Kinney 2019 edition.
any suggestions?
package.json is as follows
{
"name": "bookmarker",
"version": "1.0.0",
"description": "electron app",
"main": "./app/main.js",
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Wasim Aftab",
"license": "ISC",
"dependencies": {
"electron": "^9.0.0"
}
}
main.js is as follows
const {app, BrowserWindow} = require('electron');
let mainWindow = null;
app.on ('ready', () => {
console.log('Hello, from electron');
mainWindow = new BrowserWindow();
mainWindow.webContents.loadFile(__dirname + '/index.html');
});
index.html is as follows
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="
default-src 'self';
script-src 'self' 'unsafe-inline';
connect-src *">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Bookmarker</title>
</head>
<body>
<h1>Hello from Electron</h1>
<p>
<button class="alert">Current Directory</button>
</p>
</body>
<script>
const button = document.querySelector('.alert');
button.addEventListener('click', () => {
alert(__dirname);
// alert(window.location.pathname.replace(/[^\\\/]*$/, ''));
});
</script>
</html>
__dirname is a nodejs concept, it does not exist in the browser.
One way to resolve the issue is to set nodeIntegration to true:
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
});
Another way would be to use a preload script (nodeIntegration is always enabled for preload scripts):
mainWindow = new BrowserWindow({
webPreferences: {
preload: (__dirname + "/preload.js")
}
});
And then in the preload.js file:
window.__dirname = __dirname
For electron v16.0.4, addition of contextIsolation: false also required
$ npx electron --version
v16.0.4
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
// enableRemoteModule: true,
},
});
I have a very simple Electron app, using version 5.0.1.
Here is my index.html file:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<title>Webgl</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<script src="./initialization.js"></script>
<link rel="stylesheet" type="text/css" href="application.css">
</head>
<body>
<script>
initialization();
</script>
</html>
Then my main.js file:
const {app, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')
let win
function createWindow () {
// Create the browser window.
win = new BrowserWindow({ width: 1280,
height: 720,
nodeIntegration: true,
resizable: false,
maximizable: false })
// and load the index.html of the app.
win.loadFile('index.html')
// Open the DevTools.
win.webContents.openDevTools()
// 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
})
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null) {
createWindow()
}
})
my package.json file:
{
"name": "estimation",
"version": "1.0.0",
"description": "estimation app",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"author": "",
"license": "ISC",
"devDependencies": {
"electron": "^5.0.1"
}
}
Then my inittialization.js file that contains the initialization() method and const fs = require('fs');
const fs = require('fs');
function initialization(){
}
Now I have asked the same question in multiple places, I have tried multiple solutions, nothing works. I am wondering if this is an Electron bug at this stage.
The error I can't get rid off and I keep getting whatever I do is this Uncaught ReferenceError: require is not defined
I simply want to use require in another JS file. Why is node.js or electron not picking this up ?
Place the nodeIntegration inside webPreferences attribute
{ width: 1280,
height: 720,
webPreferences : { nodeIntegration: true },
resizable: false,
maximizable: false
}
I tried loading a web application in electron using window.loadurl and as webview in html. Application is displaying, but with different errors like:
$ jquery not defined
Uncaught TypeError: $(...).daterangepicker is not a function
Uncaught TypeError: Cannot read property 'getContext' of undefined
I tried different methods and finally get rid off '$ jquery not defined' error.
Why electron is not acting as a browser. This application is working fine on all browsers.
How can I load this web application to my electron with functionalities.
My web application is :
www.mcgeoautomation.com
My index.js file is:
const electron = require('electron');
const app = electron.app;
var path=require('path');
const BrowserWindow = electron.BrowserWindow;
var mainWindow;
app.on('ready',function(){
mainWindow = new BrowserWindow({
width: 1024,
height: 768,
backgroundColor: '#2e2c29',
show:false,
});
mainWindow.loadURL(`file://${__dirname}/webView.html`);
mainWindow.maximize(true);
// mainWindow.setMenu(null);
mainWindow.once('ready-to-show',()=>{
mainWindow.show()
})
mainWindow.on('close', (e)=>{
app.quit();
});
});
package.json file:
`{
"name": "crushmate",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "electron ."
},
"author": "",
"license": "ISC",
"dependencies": {
"electron": "^1.7.9",
"jquery": "^3.2.1"
},
"devDependencies": {
"electron-prebuilt": "^1.4.13"
}
}`
Please help...
Regards...
Electron doesn't handle jQuery the same as a regular browser does. You have to essentially inject it into the webview. Can't test this right now but should get you on the way to it working.
index.html
<!DOCTYPE html>
<html>
<head>
<title>jQuery injection into webview preload</title>
</head>
<body style="overflow:hidden;">
<webview id="webview" preload="./preload.js" src="http://www.mcgeoautomation.com" style="position:absolute;width:100%;height:100%;"></webview>
<script>
// need to have a script tag make webview work even if you don't plan to use it...
</script>
</body>
</html>
preload.js
window.onload = function() {
var script = document.createElement("script");
script.src = "https://code.jquery.com/jquery-2.1.4.min.js";
document.body.appendChild(script);
};
I ran into the same issue and deativating nodeIntegration solved it for me.
Just add following code when creating a BrowserWindow:
webPreferences: {
nodeIntegration: false
}
(The used electron version is "11.2.0")