Electron Forge中ipcRenderer的使用

記錄一次在Electron Forge中render端使用ipcRenderer與mian進程通信的踩坑經(jīng)歷。

由于能查到的中文資料較少,但是Electron Forge官方文檔說的也不是很清楚,如果你也遇到了和我同樣的問題,希望對你有幫助。

目前(2021年8月29日),Electron有兩種使用icpRenderer與主進程通信的方式:

  1. 在創(chuàng)建window的時候配置:nodeIntegration: true,然后在UI端就可以
import {ipcRenderer} from 'electron';
  1. 是使用官方推薦的contextIsolation。需要一個中介:preload.js。

于是我一個個嘗試:

嘗試nodeIntegration

第一步:按照Electron官網(wǎng)要求

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

第二步:在render進程引入ipcRenderer

import {ipcRenderer} from 'electron';
...
ipcRenderer.send("hi");
...

結(jié)果:不行。

嘗試contextIsolation

第一步:創(chuàng)建preload.js,并利用contextBridge橋接全局變量(render端可以直接訪問)

const { contextBridge, ipcRenderer } = require('electron');
// import { contextBridge, ipcRenderer } from 'electron';

contextBridge.exposeInMainWorld('electron', {
  ipcRenderer: {
    hi() {
      ipcRenderer.send('hi');
    },
  },
});

第二步:main中創(chuàng)建window時導(dǎo)入preload.js

 const mainWindow = new BrowserWindow({
    height: 600,
    width: 800,
    webPreferences: {
      preload: path.join(__dirname,"preload.js")
    },
  });

第三部:在render端使用

window.electron.ipcRenderer.hi();

結(jié)果:失敗。
1.由于使用了typescript,說我window上沒有electron屬性,所以改為:

const electron = (window as any).electron ? (window as any).electron : {send:()=>{}};

2.騙過typescript了,但是沒啥反應(yīng),查看devtools說electron是undefined。懷疑引入preload.js沒成功。所以開始各種改路徑。


中間各種折騰這里不再贅述,最后通過官方文檔加github中的幾個issue把這兩個問題都解決了,直接出結(jié)論:

第一種:直接在UI端import icpRenderer

如果你使用nodeIntegration:true的方式,即在UI端直接import ‘electron’的方式,請確保以下關(guān)鍵步驟正確:

  1. 創(chuàng)建window時設(shè)置:
webPreferences: {
   nodeIntegration: true,
   contextIsolation: false,
},

2.同時在package.json中設(shè)置

...
"config": {
    "forge": {
        ...
      "plugins": [
         [
          "@electron-forge/plugin-webpack",
          {
          ...
          "entryPoints": [
                {
                  "html": "./src/index.html",
                  "js": "./src/renderer.ts",
                  "name": "main_window",
                }
              ],
          "nodeIntegration": true // 重點:在這里也要設(shè)置true
          ...
...

第二種:使用Context Isolation的方式(preload)

官方推薦使用該方式,因為nodeIntegration存在一定安全風險。
關(guān)鍵步驟如下:

  1. 在主進程(ElectronForge目錄中為index.ts)
declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY : string;
...
  const mainWindow = new BrowserWindow({
    height: 600,
    width: 800,
    webPreferences: {
      preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY
    },
  });
...

2.在package.json中設(shè)置entry points

["@electron-forge/plugin-webpack",
  {
    "mainConfig": "./webpack.main.config.js",
    "renderer": {
      "config": "./webpack.renderer.config.js",
      "entryPoints": [
        {
          "html": "./src/index.html",
          "js": "./src/renderer.ts",
          "name": "main_window",
          "preload": {                          //
            "js" : "./src/preload.js"           // 這里是重點(看準位置哦)
          }                                    //
        }
      ],
    }
  }
]

如果你沒看懂或者還是有問題,也可以私信我,我們一起研究。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容