使用电子,反应(es6 / jsx),sass,pouchdb和webpack 2设置。我无法导入或要求ipcRenderer在主进程和渲染器进程之间进行通信。我可以在此处找到我的设置:https://github.com/wende60/timeTracker
有关如何将ipcRenderer放入反应组件的任何提示吗?
干杯,乔
答案 0 :(得分:3)
我遇到了同样的问题。这为我解决了这个问题:
添加webpack.config.js
:
const webpack = require("webpack");
module.exports = {
plugins: [
new webpack.ExternalsPlugin('commonjs', [
'electron'
])
]
...
}
然后您可以将其与
一起使用import {ipcRenderer} from "electron";
答案 1 :(得分:2)
const electron = window.require('electron');
const ipcRenderer = electron.ipcRenderer;
我认为这是更好的解决方案,因为它避免弹出React应用。
答案 2 :(得分:1)
建议您阅读我的回复here。
您将要这样设置应用程序:
main.js
const {
app,
BrowserWindow,
ipcMain
} = require("electron");
const path = require("path");
const fs = require("fs");
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;
async function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false, // is default value after Electron v5
contextIsolation: true, // protect against prototype pollution
enableRemoteModule: false, // turn off remote
preload: path.join(__dirname, "preload.js") // use a preload script
}
});
// Load app
win.loadFile(path.join(__dirname, "dist/index.html"));
// rest of code..
}
app.on("ready", createWindow);
ipcMain.on("toMain", (event, args) => {
fs.readFile("path/to/file", (error, data) => {
// Do something with file contents
// Send result back to renderer process
win.webContents.send("fromMain", responseObj);
});
});
preload.js
**更新:请勿使用
send
键值作为属性名称。当您尝试在主进程win.webContents.send
中调用win.webContents.send('your_channel_name')
时,它将覆盖main.js
方法,并且什么也不做。最好使用更好的名称,例如request
和response
。
const {
contextBridge,
ipcRenderer
} = require("electron");
// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld(
"api", {
//send: (channel, data) => {
request: (channel, data) => {
// whitelist channels
let validChannels = ["toMain"];
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data);
}
},
//receive: (channel, func) => {
response: (channel, func) => {
let validChannels = ["fromMain"];
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, (event, ...args) => func(...args));
}
}
}
);
index.html
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8"/>
<title>Title</title>
</head>
<body>
<script>
window.api.response("fromMain", (data) => {
console.log(`Received ${data} from main process`);
});
window.api.request("toMain", "some data");
</script>
</body>
</html>
答案 3 :(得分:0)
使用webpack-target-electron-renderer为此问题找到了一个很好的解决方案因此,我可以使用热重新加载在localhost环境中开发Web部件。电子仅在电子环境中需要。
你可以在这里看到一个有效的例子: https://github.com/wende60/webpack-web-and-electron-example,来自acao的webpack-web-and-electron-example,并针对webpack 2和hot-replacement进行了更新。
如果您对网络包,电子,反应,sass和pouchdb安装感兴趣,请查看: https://github.com/wende60/timeTracker 工作仍在进行中......
答案 4 :(得分:0)
我最近一直在研究这个话题,我找到了在电子main.js和应用程序的React部分之间做一些ipc的解决方案。由于import {ipcRenderer} from 'electron';
将插件添加到webpack模块并const ipc = require('electron').ipcRenderer;
产生了一些错误后,我最终在结果页面中需要电子并将其添加到窗口中。
在index.html
我做了类似的事情
<body>
...
<script>
window.ipc = require('electron').ipcRenderer;
</script>
<div id="root">
</div>
...
</body>
在做出反应index.js
时,我做了类似的事情:
import React from 'react';
import ReactDOM from 'react-dom';
// ...
if(window.ipc)
ipc.on("some-event", (event, someParameter) => {
ReactDOM.render(
<SomeElement value={someParameter} />,
document.getElementById("root")
);
})
// ...
为了完成这项工作,我从电子应用程序启动了反应页面,在main.js
我做了类似的事情。
const {app, BrowserWindow} = require("electron"};
const exec = require("child_process").exec;
let main;
app.on("ready", () => {
exec("node start", (err, stdout, stderr) => {
if(err) console.log(err);
console.log("" + stdout);
console.log("" + stderr);
});
main = new BrowserWindow();
main.loadURL("http://localhost:3006");
main.on("close", () => {main = null});
});
因为电子在同一个端口上运行,我在我的项目中添加了一个.env
文件,其中包含
PORT=3006
我使用create-react-app my-prj
(npm install -g create-react-app
)命令为我的基础项目看起来像这样
my-prj
|-package.json
|-main.js
|-.env
|-node_modules/
|-public/
|-index.html
|-src/
|-index.js
希望这篇文章有任何帮助。
答案 5 :(得分:0)
截至2020年5月,我认为Erik Martín Jordán has said it best:
创建一个preload.js文件:
total()
在main.js上:
window.ipcRenderer = require('electron').ipcRenderer;
该文件上的mainWindow变量将预加载preload.js文件。现在,React组件可以调用window.ipcRenderer方法。
在React app.js中:
// Create the browser window.
mainWindow = new BrowserWindow({
alwaysOnTop: true,
frame: false,
fullscreenable: false,
transparent: true,
titleBarStyle: 'customButtonsOnHover',
show: false,
width: 300,
height: 350,
webPreferences: {
nodeIntegration: true,
preload: __dirname + '/preload.js'
}
});
// Blur window when close o loses focus
mainWindow.webContents.on('did-finish-load', () => mainWindow.webContents.send('ping', '?') );
答案 6 :(得分:-1)
import { ipcRenderer } from "electron"
import { Component } from "react"
...
class MyComponent extends Component {
render(){
ipcRenderer.send("event", "some data")
return (<div>Some JSX</div>)
}
}