一、前言
- 因为公司有部分项目应用在window系统上,需要构建不同平台的应用程序,最后决定使用electron。
- 本篇主要给没使用过electron的,和需要简单构建应用程序的同学参考。
说明:为了避免因版本问题出现的API,或者其他错误,文中使用的版本,也是最新版本是 v9.1.1 官网
1. Electron 什么?
electron是一个结合前端的HTML,CSS,JavaScript等Web技术构建多平台的混合应用开发的github开源库。于2014年开源使用。
2.Electron 构建原理?
Electron 结合了 Chromium,Nodejs,和调用本地操作系统API,构建 Mac,window,和Linux应用程序。
Electron
的更新频率大概为2-4周。也会经常修复发现的bug,有新的API, 版本升级都会进行更新发布。
二、必备环境搭建
1. 检查node,npm环境
➜ ~ node -v
v10.16.0
➜ ~ npm -v
6.9.0
2. 安装electron
npm install electron -g
3. 创建一个项目 / 或者克隆一个仓库
- 可以更具官网的步骤创建,这里推荐选择直接克隆官网的electron-quick-start
# 克隆示例项目的仓库
git clone https://github.com/electron/electron-quick-start
# 进入这个仓库
cd electron-quick-start
# 安装依赖并运行
npm install && npm start
- 手动创建项目
- 新建一个项目目录,新建main.js,在命令行中打开当前目录
- 你也可以新建一个index.html文件,也可以不用新建,直接在后面引入你想要的页面
# 生产配置文件 package.json
npm init
- 打开main.js 配置写入如下代码
const { app, BrowserWindow } = require("electron"); // nodejs 语法,引入electron
const path = require("path");
function createWindow() { // 创建窗口函数
const mainWindow = new BrowserWindow({
width: 800,
height: 500,
// frame: false, // 无边框模式,默认为true
});
mainWindow.loadFile("./Calculator/index.html"); // 打开本地文件
// mainWindow.loadURL("https://www.baidu.com"); //打开地址
// 开发者模式,打开调试
// mainWindow.webContents.openDevTools()
}
// 准本加载函数
app.whenReady().then(() => {
createWindow();
app.on("activate", function() { // 这里主要是当窗口被激活时,如果没有窗口就创建一个窗口
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
// 窗口关闭时
app.on("window-all-closed", function() {
if (process.platform !== "darwin") app.quit();
});
- 运行
electron . <---这里是有一个 ‘ . ’的
4. 你也可以使用electron-forge
创建一个electron项目
npm install electron-forge -g
electron-forge init my-electron
cd my-electron
npm start
三、进程与线程
1.介绍
进程:正在执行的计算机程序,cpu总是运行一个进程,其他进程处于等待,一个进程中有多个线程工作。
线程:线程是操作系统运算调度的最小单位,js的运行环境一般是单线程的
我们知道JS是单线程的,而electron是底层是基于Chromium开发的,是多线程的,所以electron也是多线程的,主要分为主进程和渲染进程。
主进程
:Electron 运行package.json
的main
脚本的进程被称为主进程。 在主进程中运行的脚本通过创建web页面来展示用户界面。一个Electron应用总是有且只有一个主进程。
渲染进程
: 由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它的叫渲染进程的进程中。
普通的浏览器中运行的web页面是无法访问操作系统的原生资源的,然而Electron可以支持用户在Nodejs的API支持下对操作系统进行一些底层的交互。
2. 主进程和渲染进程之间的关系
- 主进程使用 BrowserWindow 实例创建页面。 每个 BrowserWindow 实例都在自己的渲染进程里运行页面。 当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。
- 主进程下每个web页面,和他们关联的渲染进程都是相互独立的。
3.主进程和渲染进程直接的通行
Electron
为主进程( main process)和渲染器进程(renderer processes)通信提供了多种实现方式,常见的通信方式有下面这些
- ipcRenderer 用于渲染进程
ipcRenderer.on(channel, listener)
--> channel 为事件频道,listener为触发回调函数, 用于相应webContent.send()- ipcRenderer.send(channel, data) --> 概念同上面一样,用于向ipcMain 发送一步信息
- ipcMain 用于主进程,响应渲染进程中发送的信息
ipcMain.on(channel, listener)
-->响应从ipcRender
中相同channel
event.sender
: 主进程监听到渲染进程发送的信息,在响应事件回调函数中使用event.send()
方法可以向渲染进程发送消息webContent
:ipcMain
本身是无法直接发送事件的,只能通过响应事件回调函数的event来发送,如果我们想让主进程发送消息就可以使用webContent
,webContent
是BrowserWindow
实例中的方法。- webContent.send(channel, data) --> 主进程向渲染进程发送消息
4. 不同渲染进程之间共享数据
- 可以简单使用HTML5中的API来实现,例如 localStorage 和 sessionStorage
- 在 electron 中,我们可以在主进程中讲一个对象存储为全局的变量,在渲染进程中通过模块 remote 进行操作
- 示例
// 在主进程中.
global.sharedObject = {
someProperty: 'default value'
}
// 页面 1
require('electron').remote.getGlobal('sharedObject').someProperty = 'new value'
// 页面 2.
console.log(require('electron').remote.getGlobal('sharedObject').someProperty)
四、打包
这里介绍两种打包方式
1. 正式打包,打包成一个应用程序
electron-packager <应用目录> < 应用名称> --platform=<打包平台> --out=<输出目录> ---arch=<架构> --app-version=<应用版本> --icon=<应用图标> --overwrite (是否覆盖)
- win打包:平台 --paltform=win32 | 架构 --arch=x64 | 图标 --icon=**.ico
- mac打包:平台 --paltform=drawin | 架构 --arch=x64 | 图标 --icon=**.ico
示例:
electron-packager ./ app --platform=win32 --out=./dist --arch=x64 --app-version=1.0.0 --icon=./image/icon.ico --overwite
2. 打包为安装包
下载:npm install electron-builder -g
- 配置启动脚本: 打开package.json, 可以不用全部配置
{
...
"script": {
...
"builderwin": "electron-builder -win", // 启动脚本 "buildermac": "electron-builder -mac" ...
},
build: {
"appId": "com.itcast.app", // 包名称
"directories": {
"app": "/", // 应用目录
"output": "dist" // 输出目录
},
"productName": "计算器", // 项目名称 xxx.exe
"dmg": { // 这里主要用于mac下的配置
"icon": "./xxx/mac.icns", // 图标路径
"window": { // 窗口设置
"x": "200",
"y": "150",
"width": 500,
"height": 400
}
},
"mac": { "icon": "./images/mac.icns" },
"win": {
"icon": "./images/icon.ico", // 图标路径
"extraResource": { // 拷贝dll等静态文件到指定位置
"from": "./app-update.yml",
"to": "./b.txt"
},
},
"asar": false, // asar打包
"extraResource": { // 拷贝dll等静态文件到指定位置
"from": "./app-update.yml",
"to": "./b.txt"
},
"nsis": {
"oneClick": false, // 一件安装
"guid": "xxxx", //注册表名字,不推荐使用
"perMachine": true, // 是否开启安装史权限限制
"allowElevation": true, // 允许请求提升。如果为false,用户必须使用提升的权限重新启动安装程序 "allowToChangeInstallationDirectory": true, // 允许修改安装目录 "installerIcon": "./build/icons/aaa.ico", // 安装图标 "uninstallerIcon": "./build/icons/bbb.ico", // 卸载图标 "installerHeaderIcon": "./build/icons/aaa.ico", // 安装时头部图标 "createDesktopShortcut": true, // 创建桌面图标 "createStartMenuShortcut": true, // 创建开始菜单图标 "shortcutName": "xxxx" // 图标名称
}
}
...
}