I’m encountering an issue with communication between my Angular front-end and Electron back-end using IPC. When attempting to send a message from my Angular component to my Electron main process, I’m getting the following error:
./node_modules/electron/index.js:1:11-24 - Error: Module not found: Error: Can't resolve 'fs' in '/home/user/Desktop/project/node_modules/electron'
./node_modules/electron/index.js:2:13-28 - Error: Module not found: Error: Can't resolve 'path' in '/home/user/Desktop/project/node_modules/electron'
main.js
const {app, ipcMain} = require('electron');
const {BrowserWindow} = require('electron');
const url = require("url");
const path = require("path");
let window
function createWindow () {
window = new BrowserWindow({
width: 800,
height: 600,
autoHideMenuBar: true,
webPreferences: {
nodeIntegration: true
}
});
window.setMinimumSize(800, 600);
window.loadURL(
url.format({
pathname: path.join(__dirname, `/dist/music-converter/index.html`),
protocol: "file:",
slashes: true
})
);
}
app.on('ready', createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
ipcMain.on('message-from-renderer', (event, arg) => {
console.log(arg);
event.reply('message-from-main', 'Message received in main process');
});
Angular
import { Component, OnInit } from '@angular/core';
import { ipcRenderer } from 'electron'
@Component({
selector: 'file-browser',
templateUrl: './file-browser.component.html',
styleUrls: ['./file-browser.component.scss']
})
export class FileBrowserComponent implements OnInit {
constructor() { }
ngOnInit() {
ipcRenderer.send('message-from-renderer', 'test');
}
}
Additional Context
Electron: 30.0.1
Angular: 16.2.0
- I tried another import approach:
if ((<any>window).require) {
this.ipcRenderer = (<any>window).require('electron').ipcRenderer;
}
or
ngOnInit() {
if ((<any>window).require) {
const electron = (<any>window).require('electron');
electron.ipcRenderer.send('message-from-renderer', 'test');
} else {
console.error('Electron is not available');
}
}
- Configuration of webpack.config.js: npm install path-browserify
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.ProvidePlugin({
fs: 'empty',
path: 'empty'
})
]
};
or
const path = require('path');
module.exports = {
resolve: {
fallback: {
fs: false,
path: require.resolve('path-browserify')
}
}
};
- Changing the package.json by adding:
"requires": true,
"browser": {
"fs": false,
"path": false,
"os": false
}
- Using a preload script:
preload.js
const fs = require('fs');
const path = require('path');
main.js
window = new BrowserWindow({
width: 800,
height: 600,
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true
}
});
I’ve experimented with various approaches and iterations of the suggested solutions, but I must admit that I’m feeling a bit overwhelmed. As someone who’s new to working with Electron and Angular, I’m finding myself in over my head and any help is appreciated.