Reputation: 178
I have a file that contains a function that opens a file open dialog. I want to call that function from the app's menu. But when I use require
to use the function from the file I get an error.
Code:
Main.js:
const { app, BrowserWindow, Menu } = require('electron');
const url = require('url');
const path = require('path');
const { openFile } = require('./index.js');
let win;
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
icon: __dirname + 'src/styles/media/icon.ico',
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
},
});
win.loadURL(
url.format({
pathname: path.join(__dirname, 'src/index.html'),
protocol: 'file:',
slashes: true,
})
);
var menu = Menu.buildFromTemplate([
{
label: 'File',
submenu: [
{
label: 'Open File',
click() {
openFile();
},
accelerator: 'CmdOrCtrl+O',
}
]
}]);
Menu.setApplicationMenu(menu);
}
app.on('ready', createWindow);
index.js:
const { dialog } = require('electron').remote;
function openFile() {
dialog.showOpenDialog({
title: 'Open File',
properties: ['openFile'],
});
}
module.exports = {
openFile,
};
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles/style.css" />
<title>Stonecutter</title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
When I do the same thing but without the required
the code works fine:
// index.js
// --------
// This code works
function openFile() {
console.log('Open file');
}
module.exports = {
openFile,
};
// Main.js is the same
Upvotes: 4
Views: 1503
Reputation: 6873
You're using a remote inside the main process. This is what causes the problem. Remote is what you use from Renderer process (scripts required from a BrowserView). So you need to write two different openFile functions for main and renderer processes.
So when you require index.js
from main.js
this is what cause the error. You need determine where you are in the main process or in the renderer. Watch open-file.js
below to see how to do it.
All together it should look like this:
main.js
const { app, BrowserWindow, Menu } = require('electron');
const url = require('url');
const path = require('path');
const {openFile} = require('./open-file')
let win;
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
icon: __dirname + 'src/styles/media/icon.ico',
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
},
});
win.loadURL(
url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true,
})
);
}
app.on('ready', () => {
createWindow()
var menu = Menu.buildFromTemplate([
{
label: 'File',
submenu: [
{
label: 'Open File',
click() {
openFile();
},
accelerator: 'CmdOrCtrl+O',
}
]
}]);
Menu.setApplicationMenu(menu);
})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles/style.css" />
<title>Stonecutter</title>
</head>
<body>
<button id="open-file">Open file</button>
<script>
const {openFile} = require('./open-file.js')
document.querySelector('#open-file').addEventListener('click', () => openFile())
</script>
</body>
</html>
open-file.js
const electron = require('electron');
// electron.remote for Renderer Process and electron for Main Process
const {dialog} = (electron.remote || electron)
function openFile() {
dialog.showOpenDialog({
title: 'Open File',
properties: ['openFile'],
});
}
module.exports = {
openFile,
};
This examples works as you expect. File open-file.js
is what you have in index.js
.
This is so because Electron runs its parts in different processes: the first is the Main process. It is where you're getting when running electron main.js
. The second is a Renderer process is running in a separate os process. This is where you get calling win.loadURL()
and it has slightly different API and set of libraries.
Upvotes: 3