Electron 常见问题 (FAQ)
为什么我在安装 Electron 的时候遇到了问题?
在运行 npm install electron
时,有些用户会偶尔遇到安装问题。
在大多数情况下,这些错误都是由网络问题导致,而不是因为 electron
npm 包的问题。 如 ELIFECYCLE
、EAI_AGAIN
、ECONNRESET
和 ETIMEDOUT
等错误都是此类网络问题的标志。 最佳的解决方法是尝试切换网络,或是稍后再尝试安装。
如果通过 npm
安装失败,您可以尝试直接从 electron/electron/releases 直接下载 Electron。
Why am I having trouble installing Electron?
When running npm install electron
, some users occasionally encounter installation errors.
In almost all cases, these errors are the result of network problems and not actual issues with the electron
npm package. Errors like ELIFECYCLE
, EAI_AGAIN
, ECONNRESET
, and ETIMEDOUT
are all indications of such network problems. The best resolution is to try switching networks, or wait a bit and try installing again.
You can also attempt to download Electron directly from electron/electron/releases if installing via npm
is failing.
Electron 会在什么时候升级到最新版本的 Chrome?
通常来说,在稳定版的 Chrome 发布后一到两周内,我们会更新 Electron 内的 Chrome 版本。 这个只是个估计且不能保证,取决于与升级所涉及的工作量。
我们只会使用 stable 版本的 Chrome。但如果在 beta 或 dev 版本中有一个重要的更新,我们会把补丁应用到现版本的 Chrome 上。
更多信息,请看安全介绍
When will Electron upgrade to latest Chrome?
The Chrome version of Electron is usually bumped within one or two weeks after a new stable Chrome version gets released. This estimate is not guaranteed and depends on the amount of work involved with upgrading.
Only the stable channel of Chrome is used. If an important fix is in beta or dev channel, we will back-port it.
For more information, please see the security introduction.
Electron 会在什么时候升级到最新版本的 Node.js?
我们通常会在最新版的 Node.js 发布后一个月左右将 Electron 更新到这个版本的 Node.js。 我们通过这种方式来避免新版本的 Node.js 带来的 bug(这种 bug 太常见了)。
Node.js 的新特性通常是由新版本的 V8 带来的。由于 Electron 使用的是 Chrome 浏览器中附带的 V8 引擎,所以 Electron 内往往已经有了部分新版本 Node.js 才有的崭新特性。
When will Electron upgrade to latest Node.js?
When a new version of Node.js gets released, we usually wait for about a month before upgrading the one in Electron. So we can avoid getting affected by bugs introduced in new Node.js versions, which happens very often.
New features of Node.js are usually brought by V8 upgrades, since Electron is using the V8 shipped by Chrome browser, the shiny new JavaScript feature of a new Node.js version is usually already in Electron.
如何在两个网页间共享数据?
在两个网页(渲染进程)间共享数据最简单的方法是使用浏览器中已经实现的 HTML5 API。 其中比较好的方案是用 Storage API, localStorage
,sessionStorage
或者 IndexedDB。
你还可以用 Electron
内的 IPC 机制实现。将数据存在主进程的某个全局变量中,然后在多个渲染进程中使用 remote
模块来访问它。
// 在主进程中
global.sharedObject = {
someProperty: 'default value'
}
// 在第一个页面中
require('electron').remote.getGlobal('sharedObject').someProperty = 'new value'
// 在第二个页面中
console.log(require('electron').remote.getGlobal('sharedObject').someProperty)
How to share data between web pages?
To share data between web pages (the renderer processes) the simplest way is to use HTML5 APIs which are already available in browsers. Good candidates are Storage API, localStorage
, sessionStorage
, and IndexedDB.
Or you can use the IPC system, which is specific to Electron, to store objects in the main process as a global variable, and then to access them from the renderers through the remote
property of electron
module:
// In the main process.
global.sharedObject = {
someProperty: 'default value'
}
// In page 1.
require('electron').remote.getGlobal('sharedObject').someProperty = 'new value'
// In page 2.
console.log(require('electron').remote.getGlobal('sharedObject').someProperty)
为什么应用的窗口、托盘在一段时间后不见了?
这通常是因为用来存放窗口、托盘的变量被垃圾回收了。
你可以参考以下两篇文章来了解为什么会遇到这个问题:
- 内存管理
- 变量作用域
如果你只是要一个快速的修复方案,你可以用下面的方式改变变量的作用域,防止这个变量被垃圾回收。
const { app, Tray } = require('electron')
app.on('ready', () => {
const tray = new Tray('/path/to/icon.png')
tray.setTitle('hello world')
})
改为
const { app, Tray } = require('electron')
let tray = null
app.on('ready', () => {
tray = new Tray('/path/to/icon.png')
tray.setTitle('hello world')
})
My app's window/tray disappeared after a few minutes.
This happens when the variable which is used to store the window/tray gets garbage collected.
If you encounter this problem, the following articles may prove helpful:
- Memory Management
- Variable Scope
If you want a quick fix, you can make the variables global by changing your code from this:
const { app, Tray } = require('electron')
app.on('ready', () => {
const tray = new Tray('/path/to/icon.png')
tray.setTitle('hello world')
})
to this:
const { app, Tray } = require('electron')
let tray = null
app.on('ready', () => {
tray = new Tray('/path/to/icon.png')
tray.setTitle('hello world')
})
我在 Electron 中无法使用 jQuery、RequireJS、Meteor、AngularJS。
因为 Electron 在运行环境中引入了 Node.js,所以在 DOM 中有一些额外的变量,比如 module
、exports
和require
。 这导致 了许多库不能正常运行,因为它们也需要将同名的变量加入运行环境中。
我们可以通过禁用 Node.js 来解决这个问题,在Electron里用如下的方式:
// 在主进程中
const { BrowserWindow } = require('electron')
let win = new BrowserWindow({
webPreferences: {
nodeIntegration: false
}
})
win.show()
假如你依然需要使用 Node.js 和 Electron 提供的 API,你需要在引入那些库之前将这些变量重命名,比如:
<head>
<script>
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
<script type="text/javascript" src="jquery.js"></script>
</head>
I can not use jQuery/RequireJS/Meteor/AngularJS in Electron.
Due to the Node.js integration of Electron, there are some extra symbols inserted into the DOM like module
, exports
, require
. This causes problems for some libraries since they want to insert the symbols with the same names.
To solve this, you can turn off node integration in Electron:
// In the main process.
const { BrowserWindow } = require('electron')
let win = new BrowserWindow({
webPreferences: {
nodeIntegration: false
}
})
win.show()
But if you want to keep the abilities of using Node.js and Electron APIs, you have to rename the symbols in the page before including other libraries:
<head>
<script>
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
<script type="text/javascript" src="jquery.js"></script>
</head>
require('electron').xxx
未定义。
在使用 Electron 的提供的模块时,你可能会遇到和以下类似的错误:
> require('electron').webFrame.setZoomFactor(1.0)
Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined
这是因为你在项目中或者在全局中安装了npm 上获取的 electron
模块,它把 Electron 的内置模块覆写了。
你可以通过以下方式输出 electron
模块的路径来确认你是否使用了正确的模块。
console.log(require.resolve('electron'))
确认一下它是不是像下面这样的:
"/path/to/Electron.app/Contents/Resources/atom.asar/renderer/api/lib/exports/electron.js"
假如输出的路径类似于 node_modules/electron/index.js
,那么你需要移除或者重命名 npm 上的 electron
模块。
npm uninstall electron
npm uninstall -g electron
如果你依然遇到了这个问题,你可能需要检查一下拼写或者是否在错误的进程中调用了这个模块。 比如,electron.app
只能在主进程中使用, 然而 electron.webFrame
只能在渲染进程中使用。
require('electron').xxx
is undefined.
When using Electron's built-in module you might encounter an error like this:
> require('electron').webFrame.setZoomFactor(1.0)
Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined
This is because you have the npm electron
module installed either locally or globally, which overrides Electron's built-in module.
To verify whether you are using the correct built-in module, you can print the path of the electron
module:
console.log(require.resolve('electron'))
and then check if it is in the following form:
"/path/to/Electron.app/Contents/Resources/atom.asar/renderer/api/lib/exports/electron.js"
If it is something like node_modules/electron/index.js
, then you have to either remove the npm electron
module, or rename it.
npm uninstall electron
npm uninstall -g electron
However if you are using the built-in module but still getting this error, it is very likely you are using the module in the wrong process. For example electron.app
can only be used in the main process, while electron.webFrame
is only available in renderer processes.
文字看起来很模糊,这是什么原因造成的?怎么解决这个问题呢?
如果 次级像素反锯齿已停用,那么 LCD 屏幕上的字体可能会看起来模糊。例如:
子像素反锯齿需要一个包含字体光图的图层的非透明背景。 (详情请参阅这个问题)
为了实现这一目标,在 BrowserWindow的构造器中设置背景:
const { BrowserWindow } = require('electron')
let win = new BrowserWindow({
backgroundColor: '#fff'
})
效果仅在 (有些?) LCD 屏幕上可见。即使您看不到一个差异,您的一些用户也可能显示。最好总是以这种方式设置背景,除非您有理由不这样做。
注意到,仅设置 CSS 背景并不具有预期的效果。
The font looks blurry, what is this and what can I do?
If sub-pixel anti-aliasing is deactivated, then fonts on LCD screens can look blurry. Example:
Sub-pixel anti-aliasing needs a non-transparent background of the layer containing the font glyphs. (See this issue for more info).
To achieve this goal, set the background in the constructor for BrowserWindow:
const { BrowserWindow } = require('electron')
let win = new BrowserWindow({
backgroundColor: '#fff'
})
The effect is visible only on (some?) LCD screens. Even if you don't see a difference, some of your users may. It is best to always set the background this way, unless you have reasons not to do so.
Notice that just setting the background in the CSS does not have the desired effect.