Reputation: 3104
In an Electron-React-Webpack-Typescript app, when inserting into /src/renderer.ts these lines:
ipcRenderer.on('messageFromMain', (event, message) => {
console.log(`This is the message from the second window sent via main: ${message}`);
});
I get this error:
This is the entire /src/renderer.ts file:
import './app';
console.log('renderer.js is so happy to say you 👋 hello....');
import { ipcRenderer, BrowserWindow } from 'electron';
ipcRenderer.on('messageFromMain', (event, message) => {
console.log(`This is the message from the second window sent via main: ${message}`);
});
Based on what I found here: // How to import the electron ipcRenderer in a react / webpack 2 setup , I've also put in tools/webpack/webpack.plugins.js :
const webpack = require('webpack');
module.exports = [
new ForkTsCheckerWebpackPlugin(),
new webpack.ExternalsPlugin('commonjs', [
'electron'
])
];
I tried to import electron in renderer.ts as a window component:
const electron = window.require('electron');
But got:
window.require is not a function
It must be something related to the interaction among electron, react and webpack, but I didn' find any solution yet.
With
webPreferences: {
nodeIntegration: true, // Changed
enableRemoteModule: false,
contextIsolation: false, // Changed
nodeIntegrationInWorker: false,
nodeIntegrationInSubFrames: false,
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
},
it doesn't give require is not defined
when inserting in renderer.ts:
ipcRenderer.on('messageFromMain', (event, message) => {
console.log(`This is the message from the second window sent via main: ${message}`);
});
I tried to import ipcRenderer in preload.js as follows:
window.ipcRenderer = require('electron').ipcRenderer;
But I get
TS2339: Property 'ipcRenderer' does not exist on type 'Window & typeof globalThis'.
window.ipcRenderer = require('electron').ipcRenderer;
| ^^^^^^^^^^^
Following these indications: https://github.com/electron/electron/issues/9920#issuecomment-672449613 I also handled ipcRenderer in preload.js as follows :
import { ipcRenderer, IpcRenderer } from 'electron'
declare global {
namespace NodeJS {
interface Global {
ipcRenderer: IpcRenderer
}
}
}
// Since we disabled nodeIntegration we can reintroduce
// needed node functionality here
process.once('loaded', () => {
global.ipcRenderer = ipcRenderer
})
But I get the same error in renderer.ts:
ERROR in src/renderer.ts:14:24
TS2304: Cannot find name 'ipcRenderer'.
So.. the hurdle can be expressed as: how to keep for security purposes
nodeIntegration:false,
contextIsolation: true,
and being able in the same time to import ipcRenderer in renderer.ts? There must be a way to make renderer.ts and main.ts communicate with each other, while keeping the environment as much as secure as possible.
Upvotes: 3
Views: 2015
Reputation: 3104
Yes. Now it seems working with:
in main.js
webPreferences: {
nodeIntegration: false,
enableRemoteModule: false,
contextIsolation: true,
nodeIntegrationInWorker: false,
nodeIntegrationInSubFrames: false,
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
},
preload.js :
import { ipcRenderer, contextBridge } from 'electron';
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
index.d.ts :
declare interface Window {
electron: {
doThing(): void
}
}
and renderer.ts :
import './app';
console.log('renderer.js is so happy to say you 👋 hello....');
window.electron.doThing();
Upvotes: 2