I wanted to use the following code to send a message from the renderer to the main process, which then writes it to a log file using electron-log. My main.js looks like this:
import { app, protocol, BrowserWindow } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
const { ipcMain } = require('electron');
const log = require('electron-log');
const isDevelopment = process.env.NODE_ENV !== 'production'
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { secure: true, standard: true } }
])
async function createWindow() {
// Create the browser window.
const win = new BrowserWindow({
frame: true,
width: 400,
height: 800,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
enableRemoteModule: false
}
})
ipcMain.on('infoLog', (event, args) => {
log.info(args)
});
....
Now I tried to address the IPC in my App.vue accordingly:
import Navbar from '@/components/Navbar'
const { ipcRenderer } = require('electron')
export default {
name: 'App',
components: {
Navbar
},
created: function () {
ipcRenderer.send('infoLog','A async message to main')
}
}
When I start it with yarn electron:serve
I see this error in the console of the window:
Uncaught ReferenceError: __dirname is not defined
at eval (webpack-internal:///./node_modules/electron/index.js:4)
at Object../node_modules/electron/index.js (chunk-vendors.js:2778)
at __webpack_require__ (app.js:849)
at fn (app.js:151)
at eval (webpack-internal:///./node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader-v16/dist/index.js?!./src/App.vue?vue&type=script&lang=js:5)
at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader-v16/dist/index.js?!./src/App.vue?vue&type=script&lang=js (app.js:938)
at __webpack_require__ (app.js:849)
at fn (app.js:151)
at eval (webpack-internal:///./src/App.vue?vue&type=script&lang=js:2)
at Module../src/App.vue?vue&type=script&lang=js (app.js:1099)
What I don't understand is that I set it up exactly like Electron's doc:
You have 2 different issues here:
require
The stacktrace you are seeing here likely comes from an incorrect webpack configuration. Unless told otherwise, webpack tries to replace __dirname
with something different. Here we don't want that - node provides __dirname
and we want to use it, so we have to tell webpack to leave __dirname
alone.
You'll find an example in the webpack documentation.
For webpack 5 adding a node section should help:
module.exports = {
//...
node: {
global: false,
__filename: false,
__dirname: false,
}
};
After you solved this problem you'll likely fall over the issue that your browser window does not know require
. You can reintroduce specific node API like the IPC by using a preload script. Don't activate the full node integration without knowing what you are doing.
For an example, have a look at this answer.