Electron Forge在使用Electron IPC时编译渲染器代码出现停止。

4

我正在创建一个新的electron应用程序,但遇到了一个之前从未遇到的问题。

我使用了import {ipcRenderer} from 'electron'并使用了ipcRenderer.send,但在编译渲染器代码时会显示此错误。

在最新的electron和electron forge中,在任何渲染器代码中导入electron并使用它都会导致错误并终止。

我在electron中使用React,我的上一个项目也使用了React+Electron,但是使用electron模块没有问题。

我能做的所有事情都不起作用,包括降级electron包。

完整的日志:

yarn run v1.22.10
$ electron-forge start
√ Checking your system
√ Locating Application
√ Preparing native dependencies
√ Compiling Main Process Code
√ Launch Dev Servers
√ Compiling Preload Scripts
√ Launching Application


Webpack Output Available: http://localhost:9000


\ Compiling Renderer Code

An unhandled rejection has occurred inside Forge:
[Error: EISDIR: illegal operation on a directory, read] {
  errno: -4068,
  code: 'EISDIR',
  syscall: 'read'
}

Electron Forge was terminated. Location:
{}
error Command failed with exit code 1.

我尝试重新安装所有软件包,但仍然无法工作。 为什么?如何解决? 即使我在webpack.renderer.config.json中添加了target: 'node',窗口最终能够显示,但ipcRender无法发送消息。
Uncaught TypeError: Cannot read property 'send' of undefined
    at onClick (TitleBar.tsx?3219:11)
    at HTMLUnknownElement.callCallback (react-dom.development.js?6ac8:3945)
    at Object.invokeGuardedCallbackDev (react-dom.development.js?6ac8:3994)
    at invokeGuardedCallback (react-dom.development.js?6ac8:4056)
    at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js?6ac8:4070)
    at executeDispatch (react-dom.development.js?6ac8:8243)
    at processDispatchQueueItemsInOrder (react-dom.development.js?6ac8:8275)
    at processDispatchQueue (react-dom.development.js?6ac8:8288)
    at dispatchEventsForPlugins (react-dom.development.js?6ac8:8299)
    at eval (react-dom.development.js?6ac8:8508)

为什么?

4个回答

2

我仍然遇到同样的问题,无法解决。

更新:使用preload.js来访问主进程的函数。


你能添加更多细节吗?谢谢! - TheColdPot

2

简短概述

让webpack理解electron应该使用require直接导入。

解决方案

这是一个webpack问题。

Webpack将所有使用的软件包打包成一个捆绑包。 由于electron是一个非常酷的软件包,Webpack无法将其打包成捆绑包。

配置如下,使electron成为一个commonjs2模块,将语句从import electron from 'electron'更改为直接require('electron')来获取electron中的项。

// webpack.renderer.config.js
module.exports = {
  externals: {
    electron: 'commonjs2 electron',
  },
}

太好了。谢谢你。 - Phat Tran

0
解决方案是使用electron-forge react+webpack模板中的ContextBridge API。

preload.js

import { ipcRenderer, contextBridge } from "electron";

contextBridge.exposeInMainWorld("electron", {
  notificationApi: {
    sendNotification(message) {
      ipcRenderer.send("notify", message);
    },
  },
  batteryApi: {},
  fileApi: {},
});

main.js

const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      worldSafeExecuteJavaScript: true,
      preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
    },
 });

ipcMain.on("notify", (_, message) => {
   new Notification({ title: "Notification", body: message }).show();
});

package.json

 "plugins": [
    [
      "@electron-forge/plugin-webpack",
      {
        "mainConfig": "./webpack.main.config.js",
        "renderer": {
          "config": "./webpack.renderer.config.js",
          "entryPoints": [
            {
              "html": "./src/index.html",
              "js": "./src/renderer.js",
              "name": "main_window",
              "preload": {
                "js": "./src/preload.js"
              }
            }
          ]
        }
      }
    ]
  ]

app.jsx

import * as React from "react";
import * as ReactDOM from "react-dom";

class App extends React.Component {
  componentDidMount() {
    electron.notificationApi.sendNotification("Finally!");
  }
  render() {
    return <h1>contextBridge</h1>;
  }
}

ReactDOM.render(<App />, document.body);

谢谢,但是在花费了很多时间阅读webpack文档后,我找到了更好的方法。请查看下面的内容,它可能也能解决你的问题! - TheColdPot

0

我遇到了同样的问题。我正在使用Webpack + React。

经过调查,我认为这是由于Webpack捆绑问题造成的。我们甚至不能使用@electron/remote包。

这是我的解决方法。我在preload.ts中创建了一个函数。

记得使用import * as electron from 'electron';

import * as electron from 'electron';

export function openDirectory(): void {
  const dialog = (electron as any).remote.dialog;
  console.log(
    dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] })
  );
}

enter image description here

通过contextBridge进行暴露

import { contextBridge } from 'electron';
import { getGitCommitLogs } from './core/git-api';
import { openDirectory } from './core/native-api';

contextBridge.exposeInMainWorld('getGitCommitLogs', getGitCommitLogs);
contextBridge.exposeInMainWorld('openDirectory', openDirectory);

enter image description here

在渲染器中使用它

enter image description here

启用 enableRemoteModule

const mainWindow = new BrowserWindow({
    height: 600,
    width: 800,
    webPreferences: {
      preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
      enableRemoteModule: true,
    },
  });

enter image description here

我已经发布了我的源代码和问题 https://github.com/electron-userland/electron-forge/issues/2384

这是一个很好的解决方案,但你必须在preload.ts中声明所有的方法。你可以看到我的解决方案(我读了很长时间的webpack文档)。顺便说一句,谢谢! - TheColdPot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接