Electron常见问题收录

7,177 阅读5分钟

前言

最近在使用腾讯云的 trtc-electron-sdk 开发跨平台的桌面端视频会议软件,于是准备使用 electron搭建开发环境 。

在公司网络里,安装起来顺风顺水,但到了家里远程开发时,因为没用代理,仅在安装环节就遇到了不少问题,虽然每一个都是小问题,但一个接着一个来,也让人头大。想必其他没有使用代理的初学者也会遇到这些问题。

于是决定把 Electron 的安装、运行和打包环节中遇到的问题收录一下,一来方便自己日后查阅,二来希望能帮到同路人,如有误请留言。

关键字说明

项目目录

项目中最外层 package.json 所在的目录,下文中用[项目目录]表示。

应用路径

打包后生成的程序根目录或 app 包,比如在本例表示的是:

  • mac: [项目目录]/bin/mac/xxxxxxx.app ,(此路径可以直接使用 cd 指令访问)。

  • win: [项目目录]/bin/win-unpacked

下文中统一用[应用路径]表示。

安装时遇到的问题

问题1:Electron 下载慢甚至卡住不动

当开始下载 tmp-3320-1-SHASUMS256.txt-6.1.9 文件或其它文件时,可能会特别慢,甚至在辛苦等待了很长时间后,等到的却是 npm 的 Timeout 错误:

Downloading tmp-3320-1-SHASUMS256.txt-6.1.9
[=>                                    ] 1.0% of 5.56 kB (0 B/s)

问题分析

在没有配置代理的情况下,因网络运营商的出口限制,npm 从国内直接访问国外的资源时,速度极低甚至超时失败。 是不是配置了代理就可以了呢? 也不行,因为即使我们已经给 npm 配置了代理地址,但 Electron 的安装脚本仍还是通过 IP 下载安装包的,所以代理只能加速 npm 却不能加速 Electron 的下载。

解决方案

  • 方案 A

    如果您是在家中办公,可以切换到国内的 npm 镜像:

# 指定 npm 国内镜像
$ npm config set registry=https://registry.npm.taobao.org/
# 指定 Electron 的国内镜像地址
$ npm config set ELECTRON_MIRROR=https://npm.taobao.org/mirrors/electron/ 
$ npm install
  • 方案 B 如果您是在公司办公,那么您公司的网络管理员可能已经设置了代理,需要确认 npm 的 proxy 配置是否指向了公司的代理服务器,以及是否配置了环境变量 ELECTRON_GET_USE_PROXY,如均无配置,请按以下步骤执行:
  1. 设置 npm 代理 : npm config set all_proxy=[您的代理地址]
  2. 配置 ELECTRON_GET_USE_PROXY 环境变量,这样 Electron 的安装脚本就会通过 npm 的代理下载。

如果您是 Mac 环境:

$ export ELECTRON_GET_USE_PROXY=true

如果您是 Windows 环境: 右键点击“【计算机】>【 属性】 >【 高级系统设置】>【 环境变量】” ,请按下图操作:

设置环境变量ELECTRON_GET_USE_PROXY

  1. 执行 npm installnpm install --proxy=[您的代理地址]

问题2:下载 Electron 时出现 404 错误

404 Not Found

问题分析

更换了国内的 npm 镜像地址以后,资源的下载路径出现变化。

我们可以看到,上图中出现的 404 错误地址为:http://npm.taobao.org/mirrors/electron/v8.1.1/electron-v8.1.1-darwin-x64.zip

但实际上官方源中安装地址为:http://mirrors.npmjs.org/electron/8.1.1/electron-v8.1.1-darwin-x64.zip

仔细比对就会发现:官方地址中的版本号中没有字母"v" ,而脚本在安装过程中依然拼出了带有 v8.1.1 的路径。

解决方案

在终端中输入如下指令:

$ npm config set electron_custom_dir 8.1.1 # 根据版本号来决定

其它安装问题

收集了一些用户反馈,发现他们遇到的问题不尽相同,本章节没有全部覆盖到。如果您遇到的安装问题并没有在本章列举,或者已经按以上解决方案来操作了,仍未能解决问题,那推荐您查阅[附录:手动离线安装 Electron](#附录A:手动离线安装 Electron)章节。

运行时遇到的问题

问题1:终端出现提示“Electron failed to install correctly”

当看似安装完成,运行项目时,终端上出现以下错误:

Error: Electron failed to install correctly, please delete node_modules/electron and try installing again

问题分析

安装过程看似很快就完成了,没报任何错误,而实际上 Electron 安装失败,只生成了 node_modules/electron 目录,目录中的文件不完整,脚本中的 "path.txt" 也不存在,导致运行时抛出异常。

切换到 node_modules/electron 目录下,执行 npm run postinstall 时发现:原来是下载过程中出现了 404 问题,但在项目根目录中执行 npm install 时并没有给出错误,也没终止安装进程,而是继续执行了后继安装,从而造成了安装完成的假象。

解决方案

请先阅读文章前半部分提到的安装时可能遇到的问题,并按照文章中的方案进行排障。如果依然不能解决问题,则可以按照如下三个步骤进行手动下载

  1. 执行 npm config get cache 查看缓存目录。
  2. 手动下载 Electron ,并放到缓存目录中。
  3. 重新执行npm install

问题2:调用摄像头或麦克风时直接崩溃

使用 vscode 终端启动项目,当 trtc-electron-sdk 启动摄像头和麦克风时,程序直接崩溃:

崩溃

问题分析

这个问题在新升级至 mac 10.15 的苹果电脑上出现,因为 mac 10.15 默认启动了保护机制,导致由 vscode 启动的 Electron 进程无权使用摄像头和麦克风,所以 Electron 进程会直接崩溃。

解决方案

  • 方案 A:使用有授权的终端运行项目。
  • 方案 B:给 vscode 授权:在“【系统偏好设置】>【安全与隐私】” 中允许 vscode 的授权。
  • 方案 C:按以下步骤关闭保护机制:
    1. 重启系统,按住 command + r 键,直到系统进入保护模式。
    2. 打开 terminal 输入 csrutil disable 禁用保护机制。
    3. 重启,正常进入系统,此时就可以使用 vscode 的终端启动项目了。
    4. 如需重新启动保护机制,只需要在第二步中执行csrutil enable

问题3:Electron 在控制台中报错“xx is not defined”

当运行项目时,Electron 在控制台中提示 xx is not defined,其中 xx 指代 node 模块。

例如:

Uncaught ReferenceError: require is not defined

问题分析

Electron 从 5.0 开始, nodeIntegration 配置项的默认值由 true 改为了 false ,导致默认情况下不支持 node 模块,比如 requirepath等常用模块。

解决方案

在 Electron 的 main.js 文件中将 nodeIntegration 配置项改成 true:

  let win = new BrowserWindow({
    width: 1366,
    height: 1024,
    webPreferences: {
      nodeIntegration: true,  // 请将此项设置为 true
    },
  });

打包时遇到的问题

问题1:.node 模块的加载问题

打包编译出的程序在运行时,在控制台中看到看到类似的报错信息:

  • NodeRTCCloud is not a constructor

NodeRTCCloud is not a constructor

  • Cannot open xxx/trtc_electron_sdk.node

企业微信截图_3ece5379-4cfa-4310-9d93-cb38cc5f9bdb

  • dlopen(xxx/trtc_electron_sdk.node, 1): image not found

image-20200521150704671

出现类似上述的信息,说明 trtc_electron_sdk.node 模块没有被正确的打包到程序中。

问题分析

这里为方便大家理解,需要解释一下**[工作路径]**的概念:

在 Electron 应用运行时,调用 global.process.cwd() 函数,得到的结果 “/” 即为运行时的[工作路径],当在运行时加载文件时,使用的第一个 "/" 其实都是从当前的 [工作路径] 开始的。

我们在编写构建配置的时候,很自然的会把 "/" 当成 [应用路径] 来用,然而在运行时 “/” 却代表的是 [工作路径],[工作路径] 和 [应用路径]的不一致,是造成文件加载失败的根本原因,下面罗列出了这两种路径在不同平台下运行时的关系:

  • Mac 环境: / 指向的是 [应用路径 ]/Contents/Frameworks

  • Windows 环境: / 指向的是 [应用路径]

所以,我们构建不同平台的代码时,也需要告诉程序:到不同的目录中去加载文件。

此外,还需要注意这两个问题:

  • trtc-electron-sdk.node 是 .node 模块,需要借助 native-ext-loader 插件或其它类似功能的插件来打包。

  • win 环境:trtc_electron_sdk.node 还依赖同目录下的 .dll 和 .lib 文件,需要一同打包,如下图:

dll和lib依赖

解决方案

第一步:安装 native-ext-loader

 $ npm i native-ext-loader -D

第二步:修改 webpack 配置:

 module: {
     rules: [
       { 
         test: /\.node$/, 
         loader: 'native-ext-loader', 
         options: { 
           rewritePath: os.platform() === 'win32' ? './resources' : '../Resources' 
         } 
       },
     ]
 }
  • 使用 vue-cli 创建的项目,webpack 配置存放在 vue.config.js 文件中的 configureWebpack 选项中。
  • 使用 create-react-app 创建的项目,webpack 配置文件为 [项目目录]/node_modules/react-scripts/config/webpack.config.js

第三步:修改 electron-builder 打包配置,package.json 中的 build 选项(注意大小写):

"build": {
  "省略": "...",
  "win": {
      "extraFiles": [
        {
          "from": "node_modules/trtc-electron-sdk/build/Release/",
					"to": "./resources",
					"filter": ["**/*"]
        }
      ]
  },
  "mac": {
    "extraFiles": [
      { 
        "from": "node_modules/trtc-electron-sdk/build/Release/trtc_electron_sdk.node", 
        "to": "./Resources" 
      }
    ]
  },
  "directories": {
    "output": "./bin"
  }
},

问题2:找不到入口文件

使用 create-react-app 创建的项目,使用 electron-builder 打包时可能会遇到此问题:

$ node_modules\.bin\electron-builder.cmd
  • electron-builder  version=22.6.0 os=6.1.7601
  • loaded configuration  file=package.json ("build" field)
  • public/electron.js not found. Please see https://medium.com/@kitze/%EF%B8%8F-from-react-to-an-electron-app-ready-for-production-a0468ecb1da3
  • loaded parent configuration  preset=react-cra

其中 public/electron.js not found 指的就是无法找到入口文件。

问题分析

打包 react 应用时,electron-builder 会固定的把 public/electron.js 作为 Electron 的入口文件,忽视了 package.json 中 main 选项配置的 main.electron.js 。详细信息可以参考错误信息中给出的网址,或 点击这里

解决方案

  1. 移动并重命名入口文件:
$ cd [项目目录]
$ mv main.electron.js ./public/electron.js
  1. 修改 pacakge.json 文件:
{
  "main": "public/electron.js",
  "省略": "..."
}

问题3:fs-extra 模块的语法错误

在执行打包时,出现以下错误:

[项目目录]\node_modules\electron-builder\node_modules\fs-extra\lib\empty\index.js:33
  } catch {
          ^

SyntaxError: Unexpected token {
    at new Script (vm.js:51:7)
    

问题分析

简写的 catch:try { /**/ } catch { /**/ } 是 es6 的语法,这里报语法错误,说明 node 版本太低了。

解决方案

升级到最新的 node ,请参考:nodejs官方网站

附录:手动离线安装 Electron

经实践验证,手动安装可以绕过网络问题,iMac 和 Windows 均可以按此步骤操作来完成安装。步骤稍繁琐,请逐步阅读。

操作思路

  1. 提前下载 Electron 压缩包。
  2. 在出现下载 Electron 缓慢现象或出现超时错误时,打断安装进程。
  3. 修改 Electron 安装脚本,去掉下载流程,改为直接解压已下载好的压缩包。
  4. 运行 Electron 的安装脚本,完成安装。

准备工作

  • 推荐安装官方最新的 nodejs ,安装过程请参考 nodejs官方网站
  • 本文以 electron-v8.1.1-win32-x64.zip 为例,其它操作系统请根据实际情况选择。
  • 本文使用 cmder 和 windows terminal 进行操作和验证,使用 dos 操作的朋友请自行把一些指令替换成有效的 dos 指令,比如 : mv 替换为 move

第一步:提前下载 Electron 安装包

  1. 用浏览器打开 Electorn 仓库的 release 页面: github.com/electron/el…

  2. 从列表中找到所需的版本、与操作系统匹配的压缩包,此处以 64位 windows 系统下的 electron-v8.1.1 为例:

    image-20200427173901883

  3. 点击 electron-v8.1.1-win32-x64.zip 文件下载到[项目目录]中。

下载过程需要一些时间,在等待下载的同时,进行其它步骤操作。

第二步:加入 Electron 配置并安装

编辑 package.json,把 "electron": "8.1.1",添加到 devDependencies 子项中。

 "devDependencies": {
    "省略":"...",
    "electron": "8.1.1"
  }

编辑完成后,保存退出,在[项目目录]下执行:

$ npm install

第三步:打断 Electron 的安装进程

当执行到 Electron 的安装流程时,如不出意外,终端中将出现以下两种情况:

情况1:安装进度极其缓慢:

Downloading tmp-3320-1-SHASUMS256.txt-6.1.9
[=>                                    ] 1.0% of 5.56 kB (0 B/s)

情况2:出现 ETIMEOUT 错误:

$ npm install
# 省略....
> electron@8.1.1 postinstall [项目目录]\node_modules\electron
> node install.js

(node:7208) UnhandledPromiseRejectionWarning: RequestError: connect ETIMEDOUT 52.216.240.76:443
    at ClientRequest.<anonymous> ([项目目录]\node_modules\@electron\get\node_modules\got\source\request-as-event-emitter.js:178:14)
# 省略 ...

52.216.240.76:443 (动态)并非 npm 镜像的地址,而是位于境外的 web 服务,直接访问的速度会特别慢。

此时需要按 ctrl+c 打断安装进程,开始手动安装。

第四步:修改 Electron 的安装脚本并执行安装

  1. 确认[第一步](#第一步:提前下载 Electron 安装包)中下载的 electron-v8.1.1-win32-x64.zip 文件是否完成,如下载完成,则将其移动到 [项目目录]/node_modules/electron 目录下:
$ mv [项目目录]/electron-v8.1.1-win32-x64.zip node_modules/electron
  1. 进入 [项目目录]/node_modules/electron 目录,打开 install.js 文件,在 30 行左右,可以找到以下代码:
downloadArtifact({
version,
artifactName: 'electron',
force: process.env.force_no_cache === 'true',
cacheRoot: process.env.electron_config_cache,
platform: process.env.npm_config_platform || process.platform,
arch: process.env.npm_config_arch || process.arch
}).then((zipPath) => extractFile(zipPath)).catch((err) => onerror(err))

这块代码的作用是:下载 Electron 压缩包,下载完成后调用 extractFile 方法解压到当前目录。

现在需要把它改成:直接把当前目录下的 electron-v8.1.1-win32-x64.zip 压缩文件解压到当前目录。

  1. 注释掉下载的代码,加入解压的代码:
extractFile('electron-v8.1.1-win32-x64.zip');
// downloadArtifact({
//  version,
//  artifactName: 'electron',
//  force: process.env.force_no_cache === 'true',
//  cacheRoot: process.env.electron_config_cache,
//  platform: process.env.npm_config_platform || process.platform,
//  arch: process.env.npm_config_arch || process.arch
// }).then((zipPath) => extractFile(zipPath)).catch((err) => onerror(err))
  1. 开始执行安装脚本:
$ node install.js

安装成功的情况下,终端中不会有任何输出。这个过程很快,数秒内即可完成。

第五步:运行 Electron

退回到[项目目录]下,开始运行 Electron,如能输出以下信息,并看到 Electron 的默认 UI,说明安装成功:

$ cd ../../
$ node_modules/.bin/electron

A path to an Electron app may be specified. It must be one of the following:
  - index.js file.
  - Folder containing a package.json file.
  - Folder containing an index.js file.
  - .html/.htm file.
  - http://, https://, or file:// URL.

Options:
  -i, --interactive     Open a REPL to the main process.
  -r, --require         Module to preload (option can be repeated).
  -v, --version         Print the version.
  -a, --abi             Print the Node ABI version.

image-20200428003619091