I'm building an app with electron react and MySQL, I'm stuck in preload script where i want to make my db instance available in render-er process, i got the following error
Error: module not found: ./config/db in console.
this happening when i try to require a module inside preload script.
const { app, BrowserWindow } = require("electron");
const path = require("path");
const isDev = require("electron-is-dev");
const dotenv = require("dotenv");
//load .env
dotenv.config();
function createWindow() {
// Create the browser window.
const mainWindow = new BrowserWindow({
title: "Electron",
minWidth: 800,
minHeight: 600,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
devTools: isDev,
},
});
//get url dependig on envirement (dev/prod)
const url = isDev
? `http://localhost:${process.env.PORT}/`
: `file://${path.join(__dirname, "../../dist/react/index.html")}`;
// load the url
mainWindow.loadURL(url);
// Open the DevTools.
isDev && 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.whenReady().then(() => {
createWindow();
app.on("activate", function () {
// 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 (BrowserWindow.getAllWindows().length === 0) 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", function () {
if (process.platform !== "darwin") app.quit();
});
// 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.
require("./handlers");
preload
const { contextBridge, ipcRenderer } = require("electron");
const { db } = require("./config/db");
contextBridge.exposeInMainWorld("mainApi", {
db,
});
Since Electron v20.0.0, the sandbox parameter defaults to true (according to the list of Breaking Changes)
One of the side effects of the sandbox attribute is that it can only require a few things:
A require function similar to Node's require module is exposed, but can only import a subset of Electron and Node's built-in modules:
electron (only renderer process modules)
events
timers
url
To disable sandboxing, just add sandbox: false to your webPreferences on window creation:
// ...
// Create the browser window.
const mainWindow = new BrowserWindow({
title: "Electron",
minWidth: 800,
minHeight: 600,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
devTools: isDev,
sandbox: false, // fixes require() in preloader
},
});
// ...
Related
I need to import Menu for my render.js file. But either Remote is undefined or I get some error.
With the following code I get this error:
Uncaught TypeError: Cannot read properties of undefined (reading 'members')
I also tried something from the Electron Documentation using the .enable(webContents) method, but I cannot get it working either.
What's the way of doing this?
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({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
});
render.js:
const { desktopCapturer } = require('electron');
const { Menu } = require('#electron/remote')
console.log(Menu);
As read in the npm #electron/remote doc
#electron/remote/main must be initialized in the main process before it can be used from the renderer:
// in the main process:
require('#electron/remote/main').initialize()
I actually fixed this.
First:
You need to add these lines in the index.js file:
const remote = require('#electron/remote/main');
remote.initialize()
Then, also in the index.js file, inside the createWindow() function you need to include this:
remote.enable(mainWindow.webContents);
In the render.js file to import menu:
const remote = require('#electron/remote')
const { Menu } = remote;
Check my GitHub repo where I have the files if this didn't work.
The render.js file is: https://github.com/Auax/electron-screen-recorder/blob/main/src/render.js
The index.js file is: https://github.com/Auax/electron-screen-recorder/blob/main/src/index.js
I am trying to execute a Serial Port program for windows based application using JavaScript and Arduino Uno. This is the link i referred https://channel9.msdn.com/Blogs/raw-tech/Arduino-talks-back-to-Nodejs-Drama-on-the-Serial-Port. While i try to execute the program by issuing npm start COMxx. Iam getting the following error.
App threw an error during load
TypeError: "path" is not defined: undefined
at new SerialPort (C:\serial test js\serial-app\node_modules\#serialport\stream\lib\index.js:116:11)
at Object.<anonymous> (C:\serial test js\serial-app\src\index.js:7:16)
at Module._compile (internal/modules/cjs/loader.js:1078:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1108:10)
at Module.load (internal/modules/cjs/loader.js:935:32)
at Module._load (internal/modules/cjs/loader.js:776:14)
at Function.f._load (electron/js2c/asar_bundle.js:5:12684)
at loadApplicationPackage (C:\serial test js\serial-app\node_modules\electron\dist\resources\default_app.asar\main.js:110:16)
at Object.<anonymous> (C:\serial test js\serial-app\node_modules\electron\dist\resources\default_app.asar\main.js:222:9)
at Module._compile (internal/modules/cjs/loader.js:1078:30)
And this is my code
const { app, BrowserWindow } = require('electron');
const path = require('path');
const SerialPort = require('serialport');
const Readline = SerialPort.parsers.Readline;
const portname = process.argv[2];
const myPort = new SerialPort(portname, {
baudRate:9600,
parser: new Readline("\n")
});
myPort.on('open',onOpen);
myPort.on('data',onData);
// 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({
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();
};
function onOpen(){
console.log("Open Connection");
}
function onData(data){
console.log("on Data "+data);
}
// 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.
Help me to resolve the issue
Instead :
const myPort = new SerialPort(portname, {
baudRate:9600,
parser: new Readline("\n")
});
Try this :
const myPort = new SerialPort({
path:portname,
baudRate:9600,
parser: new Readline("\n")
});
As path is a part of nodejs core module, it doesn't need to be listed explicitly
const path = require('path');
Just try to stop your solution and re-run application it should be working.
This question already has answers here:
Client on Node.js: Uncaught ReferenceError: require is not defined
(11 answers)
Closed 1 year ago.
i gone through a video link to create a simple java script based app using electron. https://www.youtube.com/watch?v=TnXz_nnQZrwI
While trying to create an app i got the following error even though i enable the nodeIntegration to true
index.html:12 Uncaught ReferenceError: require is not defined
at index.html:12
I don't know how to resolve it plz help
This is my js and Html files
my index.js file
const { app, BrowserWindow } = require('electron');
const os = require('os-utils');
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({
width: 800,
height: 600,
webPreferences:{
nodeIntegration: true
}
});
// and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, 'index.html'));
// Open the DevTools.
mainWindow.webContents.openDevTools();
os.cpuUsage(function(v){
console.log('CPU Usage (%): '+ v*100);
mainWindow.webContents.send('CPU',v*100);
console.log('Mem Usage (%): '+ os.freememPercentage()*100);
mainWindow.webContents.send('Mem',os.freememPercentage()*100);
console.log('Total Mem (GB): '+ os.totalmem()/1024);
mainWindow.webContents.send('Total-Mem',os.totalmem()/1024);
});
};
// 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.
my index.html file
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<h1>💖 Hello World!</h1>
<p>Welcome to your Electron application.</p>
<script>
const electron = require('electron');
const ipcRenderer = electron.ipcRenderer;
ipcRenderer.on('CPU',(event,data)=>{
console.log('CPU %' + data);
});
ipcRenderer.on('Mem',(event,data)=>{
console.log('Mem Usage %' + data);
});
ipcRenderer.on('Total-Mem',(event,data)=>{
console.log('Total Mem (GB)' + data);
});
</script>
</body>
</html>
For Electron >= 12, nodeIntegration: true won't work without contextIsolation: false.
https://www.electronjs.org/docs/breaking-changes#default-changed-contextisolation-defaults-to-true
Alternatively, if you do not want to take any security risks by setting nodeIntegration: true, you can make ipcRenderer available to your renderer process by creating a global variable in a "preload-file" that is called just before your renderer window is created.
In main.js create your main renderer window like this:
function createWindow () {
win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: false
}
})
win.loadFile('index.html')
}
The important part is preload: path.join(__dirname, 'preload.js').
In your preload.js you create a global variable ipcRenderer like this:
process.once('loaded', () => {
global.ipcRenderer = electron.ipcRenderer;
});
Then ipcRenderer can be used in your renderer process' html code just like that:
<script>
...
ipcRenderer.send(...);
...
</script>
I'm trying to download a torrent with Electron and Node.js using WebTorrent. Well, this is my code in main.js
const electron = require('electron')
const { app, BrowserWindow } = electron
const path = require('path')
const url = require('url')
const server = require('./server')
let win
function createWindow() {
win = new BrowserWindow ({ vibrancy: 'dark', width: 400, height: 600, frame: false, resizable: false, transparent: true })
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file',
slashes: true
}))
}
app.on('ready', createWindow)
And my code in server.js is:
require('http').createServer(function (req, res) {
var WebTorrent = require('webtorrent-hybrid')
var client = new WebTorrent()
var magnetURI = 'magnet:?xt=urn:btih:EF3B95AEF1C94FC8E98825386C3B12560FE21CFF&tr=udp://glotorrents.pw:6969/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://torrent.gresille.org:80/announce&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.coppersurfer.tk:6969&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://p4p.arenabg.ch:1337&tr=udp://tracker.internetwarriors.net:1337'
client.add(magnetURI, { path: 'movies' }, function (torrent) {
torrent.on('done', function () {
console.log('torrent download finished')
})
})
res.end('Hello from server started by Electron app!');
}).listen(9000)
The problem starts when I run the app and appears this message on the console:
(node:9032) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 ready listeners added. Use emitter.setMaxListeners() to increase limit
Its just a warning!!!
As per the Nodejs.org documentation
https://nodejs.org/api/events.html#events_emitter_setmaxlisteners_n
By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. This is a useful default that helps finding memory leaks. Obviously, not all events should be limited to just 10 listeners. The emitter.setMaxListeners() method allows the limit to be modified for this specific EventEmitter instance. The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.
So you need to add a below line in your code
"emitter.setMaxListeners(n)"
I am working on a project where I need to build a desktop app in Electron. The majority of functionality will be built in React, but there will be a part where we need to integrate a 3rd party static HTML magazine. I need some advice on how to do this. I am building a proof of concept app currently and I have based it on this https://github.com/chentsulin/electron-react-boilerplate
how would I add that on /static/ I server static HTML files. I know I could do it in express, but I really don't want to include the entire express framework just for serving static files.
I was looking at this https://www.npmjs.com/package/serve-static but have no Idea how to integrate it in my react app and bundle it into electron app.
I found another solution without using express or serve-static, we only
need to cusomize Electron built-in interceptFileProtocol() to serve static contents.
Code:(main.js)
(I use the electron-quick-start as Electron template)
function createWindow () {
window = new BrowserWindow({ width: 800, height: 600 })
window.loadURL(url.format({
pathname: 'index.html', /* Attention here: origin is path.join(__dirname, 'index.html') */
protocol: 'file',
slashes: true
}))
window.on('closed', () => {
window = null
})
}
app.on('ready', () => {
protocol.interceptFileProtocol('file', (request, callback) => {
const url = request.url.substr(7) /* all urls start with 'file://' */
callback({ path: path.normalize(`${__dirname}/${url}`)})
}, (err) => {
if (err) console.error('Failed to register protocol')
})
createWindow()
})
Reference:
protocol.interceptFileProtocol()
Explaination:
Normally, if you run React app as a normal website, all static contents should be served by HTTP [GET] method. Though they use relative paths, your HTTP server will handle the path parsing work.
However, when running under Electron, things change.
Your static contents usually use relative path like ./picture.jpg, Electron will use file protocol instead of HTTP protocol and find the file under root path like C://.//. So static contents like ./picture.jpg won't be loaded correctly.
By customizing interceptFileProtocol(), all static contents' requests will be pointed to your working directory instead of Windows(or other OS) root.
Finally, I'm not sure whether it's a good solution for all Electron projects, but if you already have a React project (or some other SPA) and want to wrap it with Electron, this solution would be fine to use.
As an addition to the great answer from #yeze322 above, here a working sample for all not so familiar with node and electron (like me). It took me some time to find out the correct require statements.
main.js (code from #yeze322 plus required imports)
const { app, BrowserWindow, protocol } = require('electron')
const path = require('path')
const url = require('url')
let mainWindow
function createWindow() {
mainWindow = new BrowserWindow({ width: 800, height: 600 })
mainWindow.loadURL(url.format({
pathname: 'index.html', /* Attention here: origin is path.join(__dirname, 'index.html') */
protocol: 'file',
slashes: true
}))
mainWindow.on('closed', function () {
mainWindow = null
})
}
app.on('ready', () => {
protocol.interceptFileProtocol('file', (request, callback) => {
const url = request.url.substr(7) /* all urls start with 'file://' */
callback({ path: path.normalize(`${__dirname}/${url}`) })
}, (err) => {
if (err) console.error('Failed to register protocol')
})
createWindow()
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
if (mainWindow === null) {
createWindow()
}
})
In your main file you have
const app = require("app")
app.on("ready", () => {
...
Here you can start the server like you would do in node.js
const serveStatic = require('serve-static')
// or
const express = require('express')
...
}
Putting 3rd patry resources in the resources directory can solve the problem