Electron with React-尝试导入 ipcRenderer - preload.js 没有被调用

问题描述 投票:0回答:1

我正在尝试使用 ipc 将页面数据发送到电子。

当我运行 elctron 应用程序时,window.ipcRenderer 只是未定义(在电子应用程序内)

这是代码 -

main.js
:

const {app, BrowserWindow, ipcMain} = require('electron')
const path = require('path')

const mainWindow = new BrowserWindow({
    width: 1080,
    height: 920,
    fullscreenable: false,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

.

ipcMain.on("play-vlc-magnet", (event, magnet) => {
  //run_script("webtorrent --vlc " + magnet)
  console.log("recevied:", magnet)
})

preload.js
console.log
不会出现在控制台中):

console.log("running preload")
window.ipcRenderer = require('electron').ipcRenderer;

在 React 组件内调用的行:

  window.ipcRenderer.send("play-vlc-magnet", r.data)

React 中的元素(写着“ipc 不存在”)

 <p>{(typeof window.ipcRenderer !== "undefined") ? "ipc renderer exists" : "ipc doesn't exist"</p>
javascript reactjs electron ipc
1个回答
4
投票

理解和实现一个有效的

preload.js
脚本可能很困难。

过去,我发现最好反复阅读以下几点,直到您了解主进程和渲染进程之间的区别、使用

preload.js
脚本的内容和原因以及如何实现工作
preload.js 脚本并与之交互
脚本。之后,天空才是极限。

preload.js
脚本中实现具体功能是常见的做法(如 Electron 文档中所示)。虽然这种方法没有任何问题,但我相信在尝试最初理解和使用这种方法时很容易感到困惑。

相反,我个人的方法是仅使用一个

preload.js
脚本并对其进行编码,以便仅通过使用白名单通道名称来传输数据。这使我能够:

  1. 对我创建的所有窗口仅使用一个
    preload.js
    脚本。
  2. 在一个地方定义所有白名单通道名称的主列表。
  3. 脚本文件大小较小,没有具体实现。
    分离关注点并将具体功能的实现放回其适当的(主和渲染进程)域中。
  4. 在下面的代码片段中,我展示了 Electron 文档中显示的程序员的“常用”方法和我常用的替代方法。您可以决定哪一个最适合您的理解和编码风格。

让我们从一个工作的
preload.js

脚本开始,这是阻止您在渲染进程和主进程之间进行通信的部分。

preload.js

(主要流程)

preload.js

作为上述“常见”
const {contextBridge, ipcRenderer} = require('electron'); contextBridge.exposeInMainWorld( 'electronAPI', { playVlcMagnet: (data) => ipcRenderer.send('play-vlc-magnet', data) } )

脚本的替代方案,以下是我个人的偏好。

preload.js

(主要流程)

preload-alt.js

以及如何使用它。

// Import the necessary Electron components. const contextBridge = require('electron').contextBridge; const ipcRenderer = require('electron').ipcRenderer; // White-listed channels. const ipc = { 'render': { // From render to main. 'send': [ 'play-vlc-magnet' // Channel name ], // From main to render. 'receive': [], // From render to main and back again. 'sendReceive': [] } }; // Exposed protected methods in the render process. contextBridge.exposeInMainWorld( // Allowed 'ipcRenderer' methods. 'ipcRender', { // From render to main. send: (channel, args) => { let validChannels = ipc.render.send; if (validChannels.includes(channel)) { ipcRenderer.send(channel, args); } }, // From main to render. receive: (channel, listener) => { let validChannels = ipc.render.receive; if (validChannels.includes(channel)) { // Deliberately strip event as it includes `sender`. ipcRenderer.on(channel, (event, ...args) => listener(...args)); } }, // From render to main and back again. invoke: (channel, args) => { let validChannels = ipc.render.sendReceive; if (validChannels.includes(channel)) { return ipcRenderer.invoke(channel, args); } } } );

接下来是您的 
/** * Render --> Main * --------------- * Render: window.ipcRender.send('channel', data); // Data is optional. * Main: ipcMain.on('channel', (event, data) => { methodName(data); }) * * Main --> Render * --------------- * Main: windowName.webContents.send('channel', data); // Data is optional. * Render: window.ipcRender.receive('channel', (data) => { methodName(data); }); * * Render --> Main (Value) --> Render * ---------------------------------- * Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); }); * Main: ipcMain.handle('channel', (event, data) => { return someMethod(data); }); * * Render --> Main (Promise) --> Render * ------------------------------------ * Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); }); * Main: ipcMain.handle('channel', async (event, data) => { * return await promiseName(data) * .then(() => { return result; }) * }); */

文件,您似乎已正确实现该文件。

main.js

(主要流程)

main.js

最后,你的 
const app = require('electron').app; const browserWindow = require('electron').BrowserWindow; const ipcMain = require('electron').ipcMain; const path = require('path'); let window; function createWindow() { const window = new browserWindow({ width: 1080, height: 920, fullscreenable: false, show: false, webPreferences: { nodeIntegration: false, // Default is false contextIsolation: true, // Default is true preload: path.join(__dirname, 'preload.js') // Use of preload.js // preload: path.join(__dirname, 'preload-alt.js') // Use of preload-alt.js } }); window.loadFile('index.html') .then(() => { window.show(); }); return window; } app.on('ready', () => { window = createWindow(); }); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { if (browserWindow.getAllWindows().length === 0) { createWindow(); } }); // --- ipcMain.on("play-vlc-magnet", (event, magnet) => { // run_script("webtorrent --vlc " + magnet) console.log("received: ", magnet) })

文件,我没有代码,但你会明白的。

index.html

(渲染过程)

index.html

	
© www.soinside.com 2019 - 2024. All rights reserved.