一、electron的地位
- 技术核心:
- Chormium
- 拥有最新的 Chromium 版本”从一种附加功能变成了一项优先考虑的任务。 这降低了版本升级之间的技术债务量。
- 因此含有Chromium 108的Electron 22将是最后一个支持版本。也从2023年一月份的23版本起,不再对win7/8进行支持
- 负责内容:最大化支持ES6标准api,封装了系统托盘、系统通知的api。
- node.js
- 运行时nodejs只是项目构建工具,本身自带运行时。
- 负责内容:网络访问控制、本地文件系统的访问控制等
- cef:由electron引领的,重量级桌面应用构建方案,是web顶级页面体验和桌面应用原生接口的折中开发方案。
- Chormium
- 背后团队:
- 历史:诞生于2013年3月13日。脱胎于github的atom shell编辑器项目,2015 年 - 正式命名为 Electron: 随着 Atom Shell 的不断发展,GitHub 决定将其开源并正式命名为 Electron。
- 1.0:2016年版本,带有一些api示例
- 12.0:2021年版本,弃用remote模块。
- Microsoft: Microsoft 对 Electron 的支持非常积极,包括收购github,他们的 github desktop、Visual Studio Code 编辑器也是使用 Electron 构建的。此外,Microsoft 还贡献了许多与 Windows 平台相关的改进和工具。
- 主流应用:
- 著名应用:vs code、postman、社交通讯的飞书、whatsapp
- 我的观察:nn、kook、discord、zoom、087助手
- 历史:诞生于2013年3月13日。脱胎于github的atom shell编辑器项目,2015 年 - 正式命名为 Electron: 随着 Atom Shell 的不断发展,GitHub 决定将其开源并正式命名为 Electron。
- 技术优势:
- 对比web应用:无他异,进行框架混合、模块导入(script式)即可。
- 对比原生桌面:Electron 还赋予你在主进程中访问 Node.js 环境的所有能力。 这组能力使得 Electron 应用能够从浏览器运行网站中脱胎换骨,并且是 Electron 文档的重点。纯前端开发生态习惯,适用于互联网桌面应用
- winform:DevExpress付费库(学习成本高、重量级)、sunnyUI免费、hzhcontrol。适用于工控应用。
- WPF:wpf是绘图界的性能顶流。适用于较复杂的工控应用。
- qt:开发难度高、收费,生态还不错但是不适用于小公司。也不适用于小型soc。适用于创新应用
- mfc:没前途。
- win ui3:ui同wpf、但是有分uwp版本和win32版本。
- ma ui:基于套壳,在Windows上就是基于win ui3,探索期,扔不太稳定。
- win32:权限相同,ui绘制底层略有不同,
- UWP:权限限制更大,WinRT,可用COM组件,ui更加兼容低版本。核心作用就是上架微软商店。所以是一种商业软件选型。
- 不足:
- 资源消耗:这是chromnuim的核心问题,无非是内存占有问题。
- 打包体积:更新麻烦,体积大还要全部重装,网络和硬盘问题。
- 版本问题:chrominum更新巨快,原生不支持win xp,23年已经不支持win7/8了。
二、开发构建
1.搭环境
- npm构建:
- 1、npm init 初始化
- 2、npm i electron--sava-dev
- 3、npm start(这是一个官方方法,使用的是当前目录下的.bin命令)
- 其他项目:
- electron-webpack:
- 区别:比原生多了服务器,支持hmr。 有配置文件和约定,十分类似于vite
- 安装依赖:yarn add webpack --dev 和 yarn add electron-webpack --dev
- 命令重置:"scripts": {
"start": "electron-webpack dev",
"build": "electron-webpack build"
} - 约定结构:project/
├─ dist/
├─ src/
│ ├─ main/
│ │ └─ index.js
│ ├─ renderer/——这是渲染进程
│ │ └─ index.js
│ └─ common/
└─ static/ - 入口写法:
let path = require('path'); let URL = require('url'); let url = ''; if (process.env.NODE_ENV !== 'production') { url = 'http://localhost:' + process.env.ELECTRON_WEBPACK_WDS_PORT; } else { url = URL.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file' }); } win.loadURL(url);
- 渲染进程的index.js:已经支持ES6的模块导入(命名导入和default默认导入)
- 配置入口模版:"renderer": {
"template": "src/renderer/index.html"
}
- vite:vite命令,vue3专属的构建工具(按需加载+dist目录esm文件)
- vue-cli:vue命令,vue的创建、构建、编译工具
- electron-webpack:
- 关于混合开发:
- 主进程:app是主进程对象;
BrowserWindow
是窗口对象。- 启动:Electron命令及运行主进程解释main.js文件,
- 如何访问渲染器dom:然而,你不能直接在主进程中编辑DOM,因为它无法访问渲染器
文档
上下文。 它们存在于完全不同的进程!但是可以通过preload.js来预访问dom对象。
- 渲染器:即一个标准的浏览器环境
- 在页面中<script src="./renderer.js"></script>,所以要使用mvvm框架也得在此处引用
- webPreferences选项:通过preload.js访问node.js原生信息:
- nodeIntegration选项:让js具有访问node.js能力
- 主进程:app是主进程对象;
- 搭框架:
- 需求:一号程序员,视野开阔
- 跟着生态走:生态是最稳定的,例如vue3的后台管理模型、组件化分法。
- 自己搭:例如mvc、写base类,例如二改后台管理,或者就是qt。
- electron的开发范式:
- 主进程:分一个controller文件夹分js写法
2.生态工具
- Electron Fiddle:可以快速验证某段代码是否可以在Electron平台上运行。
- JavaScript的能力:单线程,事件驱动型语言,但node.js多线程进一步提升了io处理能力,逻辑处理能力还是高级语言强。
- 调试:使用vscode和nodejs环境
- 配置文件launch.json:
- Ctrl+Shift+I:打开开发者工具或者win.webContents.openDevTools();
- 打包:
- 使用打包器electron-Forge:
- npm install --save-dev @electron-forge/cli
npx electron-forge import - npm run make
- 文档:Makers
- 签名:在forge.config.js里加入config: {
certificateFile: './cert.pfx',
certificatePassword: process.env.CERTIFICATE_PASSWORD
}
- npm install --save-dev @electron-forge/cli
- 使用打包器electron-Forge:
- 更新:
- 前置条件:一个更新服务器;一个自动发布插件;
- 先装代码发布器:npm install --save-dev @electron-forge/publisher-github
- npm run publish
- 自动检测更新:自动搜索相关 package.json 的
"repository"
匹配仓库。- npm install update-electron-app
- require('update-electron-app')()
- 前置条件:一个更新服务器;一个自动发布插件;
- nodemon:
三、api与原生开发
app
模块,它控制应用程序的事件生命周期。BrowserWindow
模块,它创建和管理应用程序窗口的渲染进程。- win对象:全局初始化的窗口
- 通讯:靠remote库
- 访问主进程:
- 使用remote对象:它是主进程对象(app)的映射
- getCurrentWindow():获取win对象和webContents
- BrowserWindow():构造新窗口
- 分文件导入访问主进程api的mainModel.js:
- 原理:mainModel.js仍是主进程部分。
- 仍需用remote模块导入:let mainModel = remote.require('./mainModel');
- 访问渲染进程:
- 需求:不需要在主进程改dom;但支持打印、刷新等接口。
- 通讯:
- 渲染发给主进程:ipcRenderer.send(name,参数对象)和ipcRenderer.on(name,回调)
- 主进程发给渲染:
- 多窗口和主进程通讯:
- 发送时:win对象指定窗口
- 接受并回复时:用event.sender先获取哪个窗口
- 窗口互转:让主进程中转或用ipcRenderer.sendTo()
- ipcRenderer.sendTo():需要一个win2.webContents.id
- 局限性:
- 性能问题:这是最主要的,进程通信开销问题
- 安全问题、编码混乱问题:跨进程编码的后果。
- 集成jQuery:
- 结论:不推荐在Electron应用中使用jQuery,性能下降严重。
- 非要用:
- 原理:用import完美导入到渲染进程的index.js ,index.js自动导入到index.html
- 集成vue:
- Vue CLI Plugin Electron Builder:使用vue cli作为基石
- 1.先装vue cli并创建项目:vue create my-vue
- 2.安装electron支持插件:vue add electron-builder
- 3.运行yarn electron:serve
- 项目结构:
- project/
├─ src/
├ ├ background.js——主程序入口
├ └─ main.js——渲染进程入口
├ dist_electron
└─ public
- project/
- 特点:使用了bable文件,可让主进程使用esm语法
- 手动集成:
- 条件:vite、手写配置文件、electron-win-state
- Vue CLI Plugin Electron Builder:使用vue cli作为基石
- 集成react:
- electron-react-boilerplate:自带router、redux等原生react组件
- Proton Native:是pc版的react native。
四.api使用
1.BroserWindow
- 构造器option:
- 常规:窗口相关属性x、y、width、length、
- 值得注意:frame自定义标题栏;title和icon将会跟随系统
- 文档:BrowserWindow | Electron (electronjs.org)
-
webPreferences:预加载脚本preload、开启渲染器访问nodejs能力——nodeIntegration
- show: false,用于做延迟加载(等待渲染进程的vue对象搞mouted),最后win.show()
2.ipcmain
- 19的通信:
- contextbridge:写在预渲染preload.js里暴露方法给渲染进程
- 主进程:ipcmain的handle()方法
3.原生桌面的api
- 生命周期:
- ready-to-show:不好用,因为不等JavaScript进程,不如直接在渲染流程中控制。
- 跳转页面:
- 和网页一致
- 通知
- notification{}创建——notification.show();
- 托盘图标和右击事件
- 原理:tray = new Tray(iconPath),tray是全局变量。
- 闪烁:定时器setInterval切换图标
- 注册右击事件菜单:tray.setContextMenu(menu);
- 右击事件
- 剪贴板:clipboard
- 获取图片:clipboard.readImage()获取img实例——let dataUrl = img.toDataURL(); 获取base64编码
- 菜单:
- 业务:toc应用很少用,最多保留一行导航(用户信息、app下载、充值)按钮
- 主进程 :et menu = Menu.buildFromTemplate(templateArr); Menu.setApplicationMenu(menu);
- 防抖节流:
- 目的:主要解决resize()事件
- 数据持久化:
- 本地文件:nodejs可访问,但一般不用。因为更新项目会导致原目录被删除。
- sqllite:不推荐,只推荐web api。
- localstorage:存会话级、登录状态数据。
- 记录窗口大小位置:
- LocalStorage:
- 先mounted时监听on-(max,min)>setState()
- 后mounted时getState()即打开应用时恢复
- LocalStorage:
- 禁用原生标题栏和放大缩小操作:
- 首先:webPreferences的frame:false
- 然后:tabbar的div。右侧的事件需要通信方法为getcurrentWindow.close()
- 提示关闭:
- win.on(close,event)发送给渲染进程
- 读写文件:
- 主进程:fs.watch、 dialog.showOpenDialog
- 模态窗口
- electron封装的操作系统api:dialog.showOpenDialog
本文作者为抱一只橘,转载请注明。