require cannot be used in Electron's preloadjs - electron

main.js
//...
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, './preload/preload.js')
}
});
//...
preload.js
const { contextBridge, ipcRenderer } = require('electron');
const qrcode = require('qrcode');
contextBridge.exposeInMainWorld('electronAPI', {
qrc: qrcode
})
the error
Unable to load preload script: F:\project\bluetools\preload\preload.js
Error: module not found: qrcode
Although direct exposure is not a good behavior, but I need to do it; and the example in the official documentation can be exposed directly, although it is not recommended; but why I require any third-party package in preloadjs shows "module not found: xxx"

Just add nodeIntegration: true to webPreferences. Like that.
//...
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
preload: path.join(__dirname, './preload/preload.js')
}
});
//...

I refer to here, I have got a solution, but it seems to be more troublesome, but what is this compared to security and normative?
ipc.js
module.exports = {
xxx_req: (argements) => {
const { ipcMain, winb: win } = argements;
ipcMain.on('xxx_req', (event, response) => {
win.webContents.send("xxx", "hello");
});
}
}
main.js
const ipcm = require('./ipc.js');
const createWindow = () => {
const win = new BrowserWindow({...});
ipcm.xxx_req({ ipcMain, winb: win })
}
preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
xxx_req: (response) => ipcRenderer.send('xxx_req',response),
xxx: (callback) => ipcRenderer.on('xxx',callback),
})
index.js(render process)
window.electronAPI.xxx_req("hello");
window.electronAPI.qrcode((event, detail) => {
console.log(detail)
});
If you still don't understand why I did this, please refer to here.

Related

Electron build failed to load index.html

I'm trying to build my electron application with electron-builder, I have successfully built front-end which was react and did also pass homepage: "./" in my package.json. I have also used hashbrowser as it was mentioned here
but still when I build my app, I get this message in console with white screen:
Not allowed to load local resource. I have passed webSecurity: false in webPreferences electron, It made error go away but didn't fix the problem and still getting white page.
this is my electron index.ts:
let mainWindow: BrowserWindow;
const createWidnow = () => {
mainWindowFunctions();
mainWindow = new BrowserWindow({
minHeight: 600,
minWidth: 800,
x: appXAndY.x,
y: appXAndY.y,
width: appWidthAndHeight.width,
height: appWidthAndHeight.height,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
preload: path.join(__dirname, "preload.js"),web
},
autoHideMenuBar: true,
});
mainWindow.loadURL(
isDev ? "http://localhost:3000/" : `file://${__dirname}/../build/index.html`
);
if (isDev) {
mainWindow.webContents.openDevTools();
}
}
app.whenReady().then(async () => {
createWidnow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWidnow();
}
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
db.close();
app.quit();
}
});
const mainWindowFunctions = () => {
const files = glob.sync(
path.join(__dirname, "./controllers/**/*.js").split(path.sep).join("/")
);
files.forEach((file) => {
require(file);
});
};
I tried webSecurity false but didn't help
The problem is with Electron Packager. Just use Electron Builder. Then you can get the installer using wix3.

Electron App - How do i open link in browser?

im trying to open a link in a new browser window using a Electron App.
const test = () => {
const shell = window.require('electron').shell;
shell.openExternal("https://google.com");
}
When i do this, i get error "window.require is not a function"
I have ofcourse made my research on this, and found several "fixes" but none has worked for me. I have edited my webpack.config.js to this:
module.exports = {
configureWebpack: {
externals: {
'./cptable': 'var cptable'
},
resolve: {
fallback: {
'fs': false,
'crypto': false,
'path': false,
}
}
},
}
I have also made sure nodeIntegration enabled like so:
const mainWindow = new BrowserWindow({
width: 1280,
height: 720,
webPreferences: {
nodeIntegration: true
},
autoHideMenuBar: true,
resizable: false,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
```
still no success. any idea?
renderer.js - from your renderer send request.
const response = await window.electronAPI.openLinkPlease()
preload.js - you have this middleware where your request will receive to send to electron.
process.once("loaded", () => {
contextBridge.exposeInMainWorld('electronAPI', {
openLinkPlease: () => ipcRenderer.invoke('openLinkPlease'),
})
});
electron.js - here you will get your request to open and electron will open this url in your default browser.
First add at the very beginning const {shell} = require("electron"); to add shell capabilities and than after
preload: path.join(__dirname, 'preload.js'),
},
});
add
ipcMain.handle('openLinkPlease', () => {
shell.openExternal("https://google.com");
})
This is the screen how it works from my application

Electron how to redirect users between various .html files

I am looking to try to redirect users from "home.html" to "dashboard.html". I've searched far and wide, yet I haven't found an answer.
When creating your window with the BrowserWindow module, you would have used the method win.loadFile(filePath[, options]) to load your html file.
Once the logic to change pages is successful, all you need to do is execute the win.loadFile(filePath[, options]) line of code again with the path to your new file.
As win.loadFile(filePath[, options]) returns a promise, let's add a .then() statement as well (though not requried).
main.js (main thread)
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const nodePath = require("path");
let window;
function createWindow() {
const window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
window.loadFile('home.html')
.then(() => { window.show(); });
return window;
}
electronApp.on('ready', () => {
window = createWindow();
});
// Run when logic to change to dashboard is successful.
function showDashboard() {
window.loadFile('dashboard.html')
.then(() => { window.show(); })
}

app.browserWindow returns TypeError during testing of electron app with Spectron

I am trying to run simple tests on my electron application using Spectron and mocha. However, whenever I try to use the browserWindow API I obtain an error of the form:
TypeError: Cannot read property '.....' of undefined
I did a bit of research on the internet. Some proposed solutions I found were to ensure nodeIntegration is set to true, and that DevTools is not open on the application window. I have ensured that both these criteria are satisfied, but I am still receiving the same error. What am I missing here? I am attaching my code for reference.
main.js
const {app, BrowserWindow} = require('electron')
const path = require('path')
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration:true
}
})
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()
})
test.js
const Application = require('spectron').Application
const assert = require('assert')
const electronPath = require('electron')
const path = require('path')
const { app } = require('electron')
const { expect } = require('chai')
describe('Application launch', function () {
this.timeout(10000)
before(function () {
this.app = new Application({
path: electronPath,
args: [path.join(__dirname, '.')]
})
return this.app.start()
})
after(function () {
if (this.app && this.app.isRunning()) {
return this.app.stop()
}
})
it('should be a focused window', function(){
return this.app.client.waitUntilWindowLoaded().browserWindow.isFocused().then(res => {
expect(res).to.be.true
})
})
})
The issue arises at the line this.app.client.waitUntilWindowLoaded().browserWindow.isFocused()

Opening new Window - Electron

I'm currently trying to implement a new Window on my Electron App.
So I want to include a button, and when you click on this Button, a new Window should be opened.
I didn't find anything in the Electron documentation, maybe one of you can help me.
Perhaps something like this:
const button = document.getElementById('<your_button_id>');
button.addEventListener('click', () => {
createBrowserWindow();
});
function createBrowserWindow() {
const remote = require('electron').remote;
const BrowserWindow = remote.BrowserWindow;
const win = new BrowserWindow({
height: 600,
width: 800
});
win.loadURL('<url>');
}
I believe the answer that has been taken as correct is outdated.
I have managed to do it with the ipc module and with the solution given by Nishkal.
Please, read the ipc module, I'm new to electron and not very experienced with programming. I'm sure you can come with better solutions.
Code I added in order for it to work:
my main.js
const {app, BrowserWindow} = require('electron');
const path = require('path');
//ipc
const { ipcMain } = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
createWindow();
})
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});
win.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
})
my preload.js
window.addEventListener('DOMContentLoaded', () => {
const { ipcRenderer } = require('electron')
ipcRenderer.on('asynchronous-reply', (event, arg) => {
console.log(arg) // prints "pong"
})
//button and its event listener
const b1 = document.getElementById('b1');
b1.addEventListener('click', () => {
ipcRenderer.send('asynchronous-message', 'ping')
})
})
To open a window from the renderer:
window.open("https://github.com", "_blank", "top=500,left=200,frame=false,nodeIntegration=no");
https://www.electronjs.org/docs/latest/api/window-open

Resources