Electron主进程向渲染进程自定义事件及app扩展合规性问询
1. Is using app.emit() from main to renderer via remote.app.on() a compliant practice?
First off, while your current code works (since Electron's app object is a Node.js EventEmitter instance, so emit() is a native method), this approach relies on the remote module—which has major red flags for long-term stability:
- Electron v14+ disabled
remoteby default, and it’s marked as deprecated in newer versions. The Electron team has explicitly stated they plan to remove it eventually, as it introduces performance overhead and security risks (it exposes full Node.js access to the renderer process). - Since this pattern isn’t documented, there’s no guarantee cross-process event listening via
remote.appwill work across future Electron/Node.js updates—internal changes to howremoteproxies objects could break this without warning.
The official, stable alternative is ipcMain and ipcRenderer, designed explicitly for cross-process communication and fully supported:
Main process (main.js):
const { ipcMain } = require('electron'); // Send to all renderers, or target a specific window yourBrowserWindow.webContents.send('did-something', param1, param2);
Renderer process (renderer.js):
const { ipcRenderer } = require('electron'); ipcRenderer.on('did-something', (event, param1, param2) => { $('#whatever').text(param1); });
This method is documented, maintained, and won’t break with future Electron versions.
2. Is moving database logic to main.js a good idea?
Absolutely—this is a core best practice for Electron apps:
- The main process runs with full Node.js privileges, making it the ideal place for heavy IO operations like database interactions (which can block the event loop if run in the renderer, freezing your UI).
- Separating data logic from UI code keeps your codebase cleaner, easier to maintain, and simpler to test.
- It’s more secure: you avoid exposing database credentials or raw database access to the renderer process, reducing your app’s attack surface.
Just use ipcMain/ipcRenderer to let the renderer request data operations, and have the main process handle the actual database calls and return results.
3. Can I extend the app object with custom methods/properties?
You technically can, but it’s not the cleanest or most future-proof approach. Here’s what you need to know:
- In the main process, you can directly add properties/methods to the
appinstance since it’s a regular JavaScript object:// main.js app.myCustomMethod = () => { console.log('Custom method executed'); }; app.myCustomProperty = 'My custom value'; - However, accessing these custom additions via
remote.appin the renderer runs into the sameremotedeprecation issues mentioned earlier.
A better alternative is to create a dedicated module for your custom logic, then expose it to the renderer safely using contextBridge (enabled by default in modern Electron for security):
Main process (in your preload script):
const { contextBridge, ipcMain } = require('electron'); contextBridge.exposeInMainWorld('myAppAPI', { customMethod: () => ipcMain.invoke('run-custom-method'), customProperty: 'My custom value' }); // Handle the renderer's request ipcMain.handle('run-custom-method', () => { // Your custom logic here return 'Result from custom method'; });
Renderer process (renderer.js):
// Access your custom API safely window.myAppAPI.customMethod().then(result => console.log(result)); console.log(window.myAppAPI.customProperty);
This approach keeps your custom logic separate from Electron’s built-in objects, avoids remote issues, and aligns with modern Electron security practices.
内容的提问来源于stack exchange,提问作者Dawn

