本文主要讲以下几点
- 简单介绍electron
- electron的进程与渲染层通讯
- electron的打包配置
- electron的自动更新
- electron如何集成sqlite3
- electron的资料分享
- electron在内网开发的一点点建议
- electron主进程的生命周期
快速开始一个electron与简介
electron是什么
打开官网第一眼就是使用 JavaScript, HTML 和 CSS 构建跨平台的桌面应用
,更加通俗一点就是一个桌面浏览器,实际上这样理解也是对的。因为electron就是通过javaScript使chromium来展示web页面
我为啥用它
- 前端可用制作跨平台应用
- 生态圈好
- 由github开发维护
- electron(70+k)比nw.js (35+k)Star多两倍
- electron产品我使用过表现优秀
- Vscode
- Atom
- gitHub桌面端
- ...
如何快速上手electron
我认为以下是快速开始的最好办法
- 一定要多读官方文档,可以减少大部分时间
- 官方提供的快速开始模板
- 官方提供快速熟悉的API的模板
直接使用electron官方提供的例子
// 看这个的源码,很简单可以快速上手
# 克隆这仓库
$ git clone https://github.com/electron/electron-quick-start
# 进入仓库
$ cd electron-quick-start
# 安装依赖库
$ npm install
# 运行应用
$ npm start
如果想了解这个electron的API可以克隆这个库并运行
git clone https://github.com/electron/electron-api-demos
cd electron-api-demos
npm install
npm start
如何调试electron
渲染进程调试(web页面)
渲染器进程这chrome浏览器一样,BrowserWindow创建窗口后添加窗口实例.webContents.open
主进程Electron调试
使用vsCode中的debug,注意调试路径,如果需要增加变量环境依照配置增加即可
electron中主进程的生命周期以及常用事件和渲染层
主要聊electron中主进程的生命周期,渲染器的部分生命周期,一般只介绍通用都存在的,如果只有某个系统有的api就不写在这里了,大家可以自行查阅
主进程中的生命周期
生命周期图正常流程会触发的生命周期
-
will-finish-launching
:当应用程序完成基础的启动的时候被触发 -
web-contents-created
:webContents被创建完成 -
browser-window-created
:BrowserWindow被创建完成 -
ready
:当 Electron 完成初始化时被触发 -
remote-require
: 引入remote时被调用 -
before-quit
: 在应用程序开始关闭窗口之前触发 -
will-quit
:当所有窗口都已关闭并且应用程序将退出时发出 -
quit
: 在应用程序退出时发出 -
window-all-closed
:当所有的窗口都被关闭时触发
这里要注意如果是进程杀死退出的所有都不触发,如果是
cmd+Q
或者开发者使用app.quit()
退出的window-all-closed
是不会被触发的,基本操作一般在ready中处理
进程相关
-
gpu-process-crashed
: 当 gpu 进程崩溃或被杀时触发。
其他
-
browser-window-focus
: 在 browserWindow 获得焦点时发出 -
browser-window-blur
:在 browserWindow 失去焦点时发出
渲染进程--(浏览器)-BrowserWindow
-
ready-to-show
:当页面已经渲染完成(但是还没有显示) 并且窗口可以被显示时触发 -
move
: 窗口移动 -
resize
: 调整窗口大小后触发 -
close
: 在窗口要关闭的时候触发。 它在DOM 的beforeunload 和 unload 事件之前触发. -
blur
: 失去焦点,同app -
focus
: 获得焦点,同app -
maximize
:窗口最大化时触发 -
unmaximize
: 当窗口最大化退出状态触发 -
minimize
: 窗口最小化时触发 -
restore
: 当窗口从最小化还原触发 - ...
渲染进程 BrowserWindow实例中的webContents
-
did-finish-load
:导航完成时触发,即选项卡的旋转器将停止旋转,并指派onload事件后 -
did-finish-load
: 这个事件类似于 did-finish-load, 不过是在加载失败或取消后触发 -
dom-ready
: 一个框架中的文本加载完成后触发该事件 -
crashed
: 当渲染进程崩溃或被结束时触发 -
unresponsive
: 页面未响应触发 -
devtools-opened
: 当开发者工具被打开时,触发该事件。 -
devtools-closed
: 当开发者工具被关闭时,触发该事件。 - ...
electron的进程与渲染层通讯
- 主进程和渲染器进程
- 主进程和渲染器进程的区别
chrome浏览器由于每个标签页都是一个进程,而electron所运行的进程称为主进程并且只有一个,主进程要操控浏览器的每个标签的网页称为渲染器进程,如何通讯呢?
主进程和渲染器进程
进程
进程是正在运行的程序的实例(狭义定义)
electron中的主进程
Electron 运行 package.json 的 main 脚本的进程被称为主进程。 在主进程中运行的脚本通过创建web页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。
electron中的渲染器进程
由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它自己的渲染进程中。
渲染器进程与主进程之间的区别
- 主进程是从开始运行一直存在,渲染器进程通过BrowserWindow来创建实例,实例销毁则渲染进程销毁
主进程使用 BrowserWindow 实例创建页面。 每个 BrowserWindow 实例都在自己的渲染进程里运行页面。 当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。
- 主进程管理所有渲染进程,渲染进程是独立且自我管理(web页面)
主进程管理所有的web页面和它们对应的渲染进程。 每个渲染进程都是独立的,它只关心它所运行的 web 页面。
- 主进程中可以调用底层所有的GUI的API,渲染进程则因为安全问题不能随意调用。如果要调用则需要通讯让主进程来调用。
在页面中调用与 GUI 相关的原生 API 是不被允许的,因为在 web 页面里操作原生的 GUI 资源是非常危险的,而且容易造成资源泄露。 如果你想在 web 页面里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。
主进程与渲染器进程如何通讯
主进程与渲染器进程通过ipcMain与ipcRenderer来通讯
ipcMain与ipcRenderer通讯主进程向渲染器进程通讯
这个方式主要是主进程中使用ipcMain使用on监听,监听获取后通过event.sender
(相当于webContent)send
来发送一个事件,渲染进程中使用ipcRenderer通过on来接收,如果是同步可以通过evnet.returnValue
来返回主进程的结果代码如下:
渲染器进程向主进程通讯
渲染器进程主要通过ipcRenderer这个模块中的send来发送,该方法中可以同步与异步发送消息,接收消息使用on来接收
通讯简化electron的打包
常用方式:
- electron-builder(本人主要用这个)
- electron-pakager
- electron-forge
electron-builder
electron-builder 是一个完整的解决方案,并且自带自动更新策略
electron-builder打包在package的script配置好
打包常用参数:
"build": {
"appId": "your.id", // appid
"productName": "程序名称", // 程序名称
"files": [ // 打包需要的不过滤的文件
"build/**/*",
"main.js",
"node_modules/**/*"
],
"directories": {
"output": "./dist-out", // 打包输出的目录
"app": "./", // package所在路径
"buildResources": "assets"
},
"nsis": {
"oneClick": false, // 是否需要点击安装,自动更新需要关掉
"allowToChangeInstallationDirectory": true, //是否能够选择安装路径
"perMachine": true // 是否需要辅助安装页面
},
"win": {
"target": [
{
"target": "nsis", // 输出目录的方式
"arch": [ // 输出的配置ia32或者x64/x86
"x64"
]
}
],
"publish": [ // 自动更新的配置
{
"provider": "generic", // 自己配置更新的服务器要选generic
"url": "http://127.0.0.1:8080/updata/" //更新配置的路径
}
]
}
}
在package.json中增加的快速启动项
"scripts": {
"pack": "electron-builder --dir",
"dist": "electron-builder"
}
启动打包
通常需要注意的点
- 注意路径,由于打包后的路径会有问题最好使用
path.join()
来处理一下。 - 碰到
The process cannot access the file because it is being used by another process.
这个问题多数是vscode占用了关掉重开就好了
如果配合create-react-app创建出来的应用
- 可以先让react的程序进行打包成静态文件,在把静态文件打包到electron应用中
- 如果electron-builder总是报类似
electron.js
找不到的警告,并且在上面提示让你去看网页中的方法,可以通过electron-builder提示的网址来修改,这实际是一个教程需要科学上网。
electron-builder的自动更新
如果在API中看到autoUpdater这个API,希望在看到这个API之前先参考官方的自动更新这样会让你少点坑,因为electron-builder的自动更新机制和electron提供有些不一样,electron-builder官网也有说明,否则就会一直报error了
这个更新实际上是对比例两个版本之间的版本号,如果当前版本小于,服务器版本的话就会进行下载更新
更新机制
在资料里有一篇专门讲更新机制的,很好。这里简单总结。
更新步骤.png
autoUpader生命周期
-
error
: 如果任意一个环节有问题就会走到这步 -
checking-for-update
:当开始检查更新的时候触发。 -
update-available
: 发现更新 -
update-not-available
:当没有可用更新的时候触发. -
update-downloaded
: 在更新下载完成的时候触发。 -
before-quit-for-update
: 此事件是在用户调用quitAndInstall()之后发出的。
更新要注意的点:
- electron-builder中的autoUplader需要使用
electron-updater
这个模块,非原生模块 - package.json中的publish中的url与更新的地址要一致(注意端口),否则会报
net::ERR_CONNECTION_REFUSED
- 如果是未打包也想跑一边
autoUpdater
的流程需要一个dev-app-update.yml
的文件放在与main.js
同一层级的地方,类似win-ia32-unpacked/resource/app-update.yml
这样的文件,直接复制改名就能使用 - 如果更新完成后在package中配置了自动安装的选项,在关闭应用就能直接安装,如果想自己控制马上安装需要加
autoUpdater.quitAndInstall()
- 如果初次启动应用在终端输出了你想要的结果,在渲染选只输出来了一部分,或者没有输出,如果不是报错的话,不妨监听一下该渲染进程的
did-finish-load
这个声明周期,在这里面做处理,根据场景可以使用once
来监听 - 需要一个静态网站服务器在你需要的文件夹使用
http-server -o
,如果没有就全局安装一个npm i http-server -g
,在package中需要配置publish
中的"provider": "generic"
- 碰到
spawn **/*.exe ENOENT
这类的可能是你在开发环境运行了一个未安装的应用,并且使用了autoUpdater.quitAndInstall()
就会报错,如果是安装好了就不会报这个错
//electron-quick-start
//main.js 主进程中
// 可以没有这个
const { autoUpdater } = require('electron-updater')
// ================= start 非必须 ===============
const log = require('electron-log');
autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = 'info';
// ================ end 非必须 ==================
// 封装
function sendStatusToWindow(text) {
log.info(text);
mainWindow.webContents.send('message', text);
}
/**
* 自动更新
*/
function checkUpdata() {
autoUpdater.setFeedURL('http://127.0.0.1:8080/updata/')
// autoUpdater.on('error', (error) => {
// sendStatusToWindow( `[error]:${error}`)
// })
autoUpdater.on('checking-for-update', () => {
sendStatusToWindow('Checking for update...');
// mainWindow.webContents.send('downlaod')
})
autoUpdater.on('update-available', (info) => {
sendStatusToWindow('Update available.');
})
autoUpdater.on('update-not-available', (info) => {
sendStatusToWindow('Update not available.');
})
autoUpdater.on('error', (err) => {
sendStatusToWindow('Error in auto-updater. ' + err);
})
autoUpdater.on('download-progress', (progressObj) => {
let log_message = "Download speed: " + progressObj.bytesPerSecond;
log_message = log_message + ' - Downloaded ' + progressObj.percent + '%';
log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')';
sendStatusToWindow(log_message);
mainWindow.webContents.send('downloadExe', progressObj.percent)
})
autoUpdater.on('update-downloaded', (info) => {
mainWindow.webContents.send('downloaded')
sendStatusToWindow('Update downloaded');
// autoUpdater.quitAndInstall();
});
electron中添加sqlite3
需要的环境
如果是windows环境需要准备 vs2015 与python2.7的环境
- python2.7.x 网上下载安装即可
- vs2015 以下方式可选其一
- 工具包
npm install --vs2015 -g windows-build-tools
(推荐) - 安装visual studio 中安装vs2015工具包(超久)
- 工具包
程序中可添加的本地数据库,最多使用的两款
- sqlite3(关系型)
- neDB(非关系型)
为自己的数据加上本地数据库sqlite3
sqlite3【gitHub】
为程序添加sqlite3npm i sqlite3
或者yarn add sqlite3
如何使用?
// 官网例子
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database(':memory:'); // 这里是把数据存入内存
db.serialize(function() {
var db = new sqlite3.Database()
db.run("CREATE TABLE lorem (info TEXT)");
var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
for (var i = 0; i < 10; i++) {
stmt.run("Ipsum " + i);
}
stmt.finalize();
db.each("SELECT rowid AS id, info FROM lorem", function(err, row) {
console.log(row.id + ": " + row.info);
});
});
db.close();
sqilte3在安装的时候自动生成sqlite所需要的文件包,这个二进制文件需要使用node-pre-gyp
或者是node-gyp
这也就是为什么需要安装环境的原因,在这一步鬼知道当时报了多少东西,尤其是还要把这玩意弄进内网。
比如说:
- 开始运行的时候就报
Error: Cannot find module 'E:\electronjs\electron-quick-start\node_modules\sqlite3\lib\binding\electron-v4.0-win32-x64\node_sqlite3.node'
类似这样的东西,实际上确实没有这个东西,怎么解决呢?- 使用
node-gyp
这个模块直接重新编译一个版本正确的
- 使用
node-gyp rebuild
--target=4.0.4 --arch=x64
--target_platform=win32 --dist-url=https://atom.io/download/electron/
--module_name=node_sqlite3 --module_path=../lib/binding/electron-v4.0-win32-x64
// 使用到的模块解析
// target => electron的版本号一定要一直
// target_platform => 需要打包的平台ia32/x64等
// dist-url => 这个是需要下载相关内容的地址
// module_name => 需要打包的模块名称
// module_path => 打包输出的地方
如果觉得麻烦可以试试npm i electron-rebuild -D
然后在使用./node_modules/.bin/electron-rebuild
重新编译一遍,有时候可能是缓存问题,把缓存清除npm cache clear -f
清除一下,还有就是npm i
重新安装一下,因为环境的问题会跳出各种问题,可以多多尝试这些方法
was compiled against a different Node.js version using
NODE_MODULE_VERSION 64. This version of Node.js requires
NODE_MODULE_VERSION 69. Please try re-compiling or re-installing
如让你选择node编译版本的github【issues】====>也有可能是编译问题,利用electron-rebuild 重新编译一遍或者把sqlite3降级
需要注意的
- 打包的时候如果报
error MSB4019: 未找到导入的项目Microsoft.WebApplication.targets
重新安装一下vs2015工具包,或者以前安装的有问题重新安装(我就碰到了) - 用node-gyp编译sqlite3打包需要
binding.gyp
这个python文件以及其他配置所以直接进入node_modules\sqlite3
这个文件运行 node-gyp的操作 - 打包的时候要注意在渲染进程中使用sqlite3在打包的时候会出现打包问题,解决可以选在在主进程操作本地数据库
- 打包之后使用DB会出现一个问题,在当前目录怎么都生成不了DB,在网上查了要么就通过手动授权为管理员打开,要么手动管理员打开,这根本就不能行,后来参考
electron-vue
发现可以使用app.getPath('userData')
这个方法进行获取app可缓存地址,然后使用path.join
合并一下路径就解决了无法生成DB文件的问题,事实上indexDB,locaStore这个两个的存储文件也在这个目录下
其他模块
-
globalShortcut
: 注册全局快捷键 -
Tray
: 托盘 -
Menu
:菜单事件
内网开发需要注意
内网开发真的很烦。。
首先需要环境,然后就是需要下载的包,其次就是需要编译后的各种文件如sqlite3编译后的文件等如果在内网开发electron就需要把这些需要的包全都复制到对应位置
大部分需要配置的文件都在C:\Users\xxx
xxx代表你所在的文件夹,
部分下载缓存文件在C:\Users\xxx\AppData\Local
目录下的electron 和 electron-builderer里
参考的学习资料
以下文章大部分阅读过,觉得不错推荐给大家
electron
- electron官网-文档必啃,少踩80%的坑
- Electron,从玩玩具的心态开始,到打造出一款越来越优秀的桌面客户端产品 —— 一份不是「Hello Word」的吊胃口的Quick Start
- 【译】Electron 的本质
- 【科学上网】从React到准备生产的Electron应用程序
- 苏南大叔的electron集合
- [electron]终极奥义 五千字教程丢给你
- Electron构建跨平台应用Mac/Windows/Linux
- Electron 深度实践总结
- 【科学上网】electron相关基础
electron构建相关
- Electron 应用如何利用 create-react-app 从 0 到1
- Electron系列文章-程序目录结构
- Webpack实战-构建 Electron 应用
- React + Electron 搭建一个桌面应用
electron打包相关
- electron-builder官网
- 了解 Electron 打包
- 用 Electron 打造 Win/Mac 应用,从「代码」到可下载的「安装包」,可能比你想得麻烦一点
- 打包优化
- 双package方案
- electron-builder打包见解
electron更新
electron
- 使用 Electron 构建桌面应用
- 如何使用Electron使用JavaScript构建您的第一个桌面应用程序
- 使用Electron构建Todo应用程序-科学上网
- XCel 项目总结 - Electron 与 Vue 的性能优化【凹凸实验室】
网友评论