Electron 踩坑

4,342 阅读3分钟

前言

本文是个人根据极客时间课程学习使用 Electron 过程中遇到的一些问题整理收集而来。避免后续重复踩坑。


本机配置

系统版本: win10

electron 版本 10.0.0

包管理工具:yarn

网络环境: 能够访问外网

electron 安装

yarn global add yrm
yrm use taobao
yarn add electron

请务必使用淘宝源进行安装或者确保你的网络能够正常访问 github

C++模块安装

yarn add robotjs

类似 robotjs 这样的使用 C++ 模块的库在不同的平台和Node.js版本下安装需要重新编译,根据 node-gyp 项目上issue的说法,在windows上安装存在两种方法:

  1. 使用管理员权限打开cmd或者powershell,然后
yarn global add windows-build-tools

(但我实际在自己电脑上测试失败,只能尝试第二种方法去安装Visual Studio)

  1. 安装最新版Visual Studio Community(目前最新版是2019),安装时勾选 C++ 桌面开发环境,然后
yarn config set msvs_version 2019 // 设置为你安装的Visual Studio Community 版本

安装后运行 yarn add robotjs 应该就不存在报错,但实际运行仍然会提示模块不可用。可以安装 electron-rebuild ,然后执行 npx electron-rebuild,就可以解决。

报错: require is not defined

需要在创建窗口时启用 nodeIntegration,这样在窗口中才可以使用 require 和 process 这样的 node APIs。不过官方推荐的做法是使用 preload,详情见官方文档

function createWindow() {
  win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: { nodeIntegration: true }, // 设置为true
  })
}

在 create react app 中 import electron 模块失败

因为 webpack 无法解析 electron 的依赖,解决方法:

  1. 使用 window.require 引入
window.require('electron')
  1. 篡改 cra 的 webpack 配置
yarn add customize-cra react-app-rewired

根目录添加 config-overrides.js 文件,内容为

const {override} = require('customize-cra')

function addRendererTarget(config){
    config.target = 'electron-renderer'
    return config
}

module.exports = override(addRendererTarget)

cra 项目中的 package.json 中 scripts 改为

"scripts":{
    "start":"BROWSER=none react-scripts-rewired start"
}

这样就可以成功运行 import electron

报错:remote is undefined(获取不到 remote 模块)

electron 10 默认禁用了 enableRemoteModule,如果需要使用请手动设置为 true。

win = new BrowserWindow({
  webPreferences: {
    nodeIntegration: true,
    enableRemoteModule: true, //设置为true
  },
})
为什么不建议使用 remote 模块

remote 本质上是基于 IPC 的一个同步的进程间消息,同步 IPC 会影响 UI 渲染。

报错: An object could not be cloned

在渲染进程中如果使用 ipcRenderer.send 或者 ipcRender.invoke 传递参数,参数的类型不能是 函数 ,Promise,Symbols,WeakMaps 或 WeakSets. 在 Electron 9 之后的版本,发送非标准的 JavaScript 类型比如 DOM 对象或者特殊的 Electron 类型也会抛出错误。 如果需要发送类似的对象,可以先使用 JSON.stringify 转换成字符串

ipcRenderer.send('forward', 'puppet-candidate', JSON.stringify(e.candidate))

警告: Electron Security Warning(Insecure Content-Security-Policy)

需要在 HTTP header 设置网页的内容安全策略,如果通过 file 协议加载,建议加上 HTML 标签

<meta http-equiv="Content-Security-Policy" content="default-src 'none'" />

实测加上该标签会导致 JS 加载失败,具体原因有待研究。此条参考自官方文档

警告: webFrame.executeJavaScript was called without worldSafeExecuteJavaScript enabled

要消除这个警告需要在创建窗口时设置 worldSafeExecuteJavaScript 和 contextIsolation 为 true

function createWindow() {
  win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: { worldSafeExecuteJavaScript: true, contextIsolation: true }, // 设置为true
  })
}

注意:设置为 true 会导致在窗口中无法直接使用 node api


参考链接:

  1. Windows10环境下npm或yarn安装node-gyp依赖出错解决方案
  2. electron-require-is-not-defined
  3. Electron 官方文档
  4. security-warning-in-the-console-of-browserwindow-electron-9
  5. 极客时间 Electron 开发实战
  6. 【Electron】躺坑记录集合-2020