快速开始
简介
是什么是 Electron?
首先它是一个框架 (framework), 然后他是用于构建桌面应用的. 他使用的是 JavaScript, HTML 和 CSS 技术. 其次他将 Chromium 和 Node 嵌入到二进制文件中.
electron 支持你维护一段 JS 代码, 然后创建跨平台的桌面应用, 可运行与 Linux, Windows, 以及 MacOS 上.
开始
官方推荐使用教程 tutorial 开始. 它从开始编写代码, 到发布都进行了介绍.
案例与 API 文档则是用于扩展与查阅.
使用 Electron Fiddle 来运行案例
Electron Fiddle 是一个沙箱 app. 它使用 electron 编写. 我们推荐在学习的时候一定要安装它来体验与学习.
Fiddle 集成了案例, 在文档与教程中常会看到在 Fiddle 中打开, 即是如此. 它会自动访问网络上的案例, 而不用你下载与编写代码即可看到效果.
文档中有什么
所有的文档都在侧边栏中展示. 下面介绍每一个分类:
- Tutorial 教程. 手把手教你如何开始编写你的第一个 Electron 应用, 以及如何发布你的应用.
- Process in Electron: 深入 Electron 的处理过程, 并介绍其如何工作的.
- Bast Practices: 开发过程中应该记住的一些内容.
- Examples: Electron 中的特性的一些快速演示.
- Development: 各种开发杂项
- Distribution: 介绍如何发布
- Test and Debug: 介绍如何调试 JavaScript, 如何编写测试, 以及其他工具. 用于创建高效的 Electron app.
- Rederence: 一些介绍 Electron 项目是如何工作的链接, 以及组织结构.
- Contributing: 贡献
获得帮助
快速开始
本指南会手把手介绍创建 Electron 应用的过程, 类似于 electron/electron-quick-start.
最后, 你的应用会展示 Chromium, Nodejs, 以及 Electron 版本.
预先要求
首先需要安装 Node.js, 推荐使用 长期支持版.
检查 node 版本可以使用:
node -v
npm -v
需要注意的是, Electron 中也嵌入了 node 环境, 其版本与你系统中的版本可能不一致.
创建你的应用
项目脚手架
Electron 项目与其他 Nodejs 项目类似, 具有一定文件夹结构.
mkdir my-electron-app && cd my-electron-app
npm init # npm
yarn init # yarn
init
向导会提示输入一些内容, 这里需要注意的是:
entry point
必须是main.js
author
与description
可以是任意值, 但是如果需要打包发布就必须提供数据.
然后安装 electron 包
npm i -D electron
# 或者
yarn add -D electron
这里需要注意, 使用环境变量配置源
$ENV:ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
最后要执行 Electron, 在 scripts 字段中添加下面脚本:
{
"scripts": {
"start": "electron ."
}
}
执行 npm start
即可打开 app, 并以开发模式运行.
注意: 该命令会告诉 electron 在项目根目录下运行, 并会立即得到一个错误, 找不到运行的文件.
运行 main 进程
Electron 应用的入口点为 main
脚本. 该脚本控制了主进程 (main process), 它会运行在完整的 Node 环境中. 并且它会控制应用的生命周期. 也会维护渲染进程.
相当于主程序
在运行的时候, Electron 会通过 package.json 的 main 字段来确定执行什么脚本.
初始化 main 脚本, 则在项目根目录下创建 main.js
文件.
再次运行程序不会有任何结果, 因为没有提供任何代码. 但不会报错.
创建 Web 页面
在 Electron 应用中, 所有的界面都是 HTML 页面. 因此需要提供 HTML 页面或, 可用的 URL.
在本教程中, 在根目录下创建 index.html
文件.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</body>
</html>
页面中通过 ID 保留了一些占位符, 后面会使用 JS 替换其中数据.
在浏览器窗口中打开 web 页面
现在有了页面, 需要加载该页面 需要两个模块:
app
模块, 该模块控制应用程序事件的生命周期.BrowserWindow
模块, 它可以创建并管理应用程序窗口.
由于主进程运行在完整的 Node 环境下, 因此可以在页面的顶部使用 CommonJS
模式导入这两个模块:
const { app, BrowserWindow } = require('electron')
然后提供 createWindow()
函数, 在新的 BrowserWindow
实例加载 html
页面
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
然后调用 createWindow()
方法来打开窗口.
在 Electron 中, 浏览器窗口必须在 app
模块的 ready
事件触发后再创建. 你可以使用 app.whenReady()
API 来等待事件触发. 在 whenReady()
之后调用 createWindow()
.
app.whenReady().then(() => {
createWindow()
})
在该过程中, electron 则会展示 HTML 页面.
管理窗口生命周期
需要一些特殊的方法让应该在不同平台上运行更合乎逻辑.
一般可以使用 process
的全局属性 platform
来获得平台信息.
当所有窗口关闭时推出程序 (Win / Linux)
这个模式适用于 WIndows 和 Linux 平台, 只需要监视 window-all-closed
事件, 然后调用 app.quit()
方法. 但是若是 MacOS 平台 (darwin). 则不同.
app.on('window-all-closed', () => {
if (process.platform != 'darwin') app.quit()
})
如果没有窗口则打开一个窗口(macOS)
在 mac 上, 及所有窗口都关闭了, 应用依旧还在运行. 因此在激活该应用时, 若没有窗口就创建一个.
app.whenReady().then(() => {
createWindow()
app.on('active', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
此时, 窗口的控制已经完整.
使用 preload 脚本在渲染函数上访问 Node.js
下面需要在页面中显示各个版本信息.
这里使用 Node 的 process 对象来获得需要的信息. 但是在 主进程中无法进行 DOM 操作. 因为此时无法访问渲染进程.
详细了解 Electron 进程的信息, 可以参考 进程模块的文档.
这里就需要使用 preload 脚本了, 该脚本运行在渲染进程之前, 并且可以访问到渲染全局对象 (window
和 document
) 以及 Node.js 环境.
创建 preload.js 文件, 内容如下:
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[denpendency])
}
})
要附加该脚本到渲染进程中, 将该脚本的路径传入 webPreferences.preload
中, 在 BrowserWindow
构造函数中.
const { app, BrowserWindow } = require('electron')
const path = require('path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.resolve(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
这里使用 path
模块, 是的应用在本地或打包的时候均可以访问到 html.
Bonus: 在页面中添加额外功能
实际上就是一个 js 文件, 通过 script 标签导入. 这里可以是:
- 原生 js.
- 使用 webpack 打包的 js.
- Vue 或 React 或 Angular 等生成的模块.
Recap
按照上面的处理办法后即可得到完整的 Electron 应用.
发布应用程序
最快的方法是使用 Electron Forge
- 安装 Electron Forge
- 使用 import 命令来导入脚手架
- 使用 make 命令进行发布
yarn add -D @electron-forge/cli
npx electron-forge import
yarn make
安装的高级说明
安装 Electron
的预编译二进制文件使用 npm
. 推荐的方法是采用 开发依赖 的方式安装:
npm install electron --save-dev
参考 Electron 版本的文档来介绍如何管理应用的 Electron
版本.
运行 Electron ad-hoc
如果不想要安装, 可以使用 ad-hoc, 通过 npx
命令来启用 Electron
:
npx electron .
上述命令会在当前根目录启用 electron. 注意, 不会安装任何依赖.
自定义
如果想要配置 cpu 的架构, 安装时可以带上 --arch
参数, 或设置环境变量 npm_config_arch
:
npm install --arch=ia32 electron
除了修改 CPU 架构, 还可以设置平台, 使用参数 --platform
:
npm install --platform=win32 electron
代理
如果需要使用 HTTP Proxy 需要设置环境变量 ELECTRON_GET_USE_PROXY
.
但是配置方式与 Node 版本有关系, 分界点为 Node 10 的版本.
自定义镜像与缓存
安装过程中, electron
模块会通过 @electron/get
下载符合当前平台的 Electron 预编译二进制文件. 它会连接到 GITHUB 下载页面:
https://github.com/electron/electron/releases/tag/v$VERSION
其中 $VERSION
是 electron 版本号.
如果你无法访问 GitHub 那么就需要自行提供构建的二进制文件. 你可以使用镜像, 或缓存文件夹.
镜像
你可以使用环境变量覆写基础 URL, 路径参考 Electron 二进制文件名. URL 由 @electron/get
合成, 格式为:
url = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME
例如中国镜像为:
ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
jk: 所以在命令行中运行之前, 使用
$ENV:ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
默认情况下, ELECTRON_CUSTOM_DIR 设置为 v$VERSION. 修改该格式使用 {{ version }}
占位符. 例如 version-{{ version }}
会生成形如 version-5.0.0
的内容. 而 v{{ version }}
与之等价. 更多示例, 参考中国的非 CDN 镜像:
ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
ELECTRON_CUSTOM_DIR="{{ version }}"
上述配置会在 url
https://npmmirror.com/mirrors/electron/8.0.0/electron-v8.0.0-linux-x64.zip
下载文件.
如果你的镜像与官方镜像的校验算法不同, 还需要使用环境变量 electron_use_remote_checksums=1
来使用远程的 SHASUMS256.txt
文件来进行校验.
缓存
另一个方法是使用缓存, 那么 @electron/get
会使用缓存中的数据, 而不是进行网络请求:
- Linux:
$XDG_CACHE_HOME
或~/.cache/electron/
- macOS:
~/Library/Caches/electron/
- Win:
$LOCALAPPDATA/electron/Cache
或~/AppData/Local/electron/Cache/
如果环境中使用早期的 Electron, 你也可以在 ~/.electron
中找到缓存.
你可以可以使用环境变量 electron_config_cache
来修改缓存目录.
缓存目录中含有二进制文件, 以及校验文件. 存储与 [checksum]/[filename]
目录下.
跳过二进制文件的下载
electron 由 Node 和 Chromium 模块强耦合而成, 因此每次下载都会重复下载 node 等模块. 如果你需要下载, 但不需要 electron 的功能, 可以跳过减少下载的内容.
只需要配置环境变量: ELECTRON_SKIP_BINARY_DOWNLOAD
这一方式在持续集成, 或在脱离 electron 功能进行单元测试的时候效率很高.
ELECTRON_SKIP_BINARY_DOWNLOAD=1 npm install
排错
在运行 npm i electron
的时候常会出现错误.
通常这些错误都是因为网络问题造成的, 而不是 npm 包邮问题. 诸如出现 ELIFECYCLE
, EAI_AGAIN
, ECONNRESET
, 以及 ETIMEOUT
等关键词时, 都表示是网络问题. 最好的解决办法是选择不同网络, 或等待安装.
如果使用 npm 安装失败, 也可以直接从 electron/electron/release 直接下载.
如果出现 EACCESS
的错误, 那么应该提高 npm
的权限.
如果上述问题依旧存在, 需要使用:
sudo npm install electron --unsafe-prm=true
针对较慢的网络, 可以使用 --verbose
来查看具体问题.
npm install --verbose electron
如果需要重新下载, 则设置环境变量 force_no_cache=true