简介
electron是使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序。通过将 Chromium 和 Node.js 嵌入其二进制文件中,Electron 允许你维护一个 JavaScript 代码库,并创建可在 Windows、macOS 和 Linux 上运行的跨平台应用程序——不需要原生electron开发经验。
为什么用Electron
- Electron 是一个框架,使开发者能够将 Web 技术(HTML、JavaScript、CSS)、Node.js 及原生代码相结合,构建适用于 macOS、Windows 和 Linux 的跨平台桌面应用程序。 它基于MIT开源许可证,对商业和个人用途均免费。
- 多功能性:无论你的应用程序需要什么样的界面,都可以使用 HTML、CSS 和 JavaScript 来实现。
- 可靠性:从 CPU 到操作系统,现代计算机都经过了优化,可以很好地运行 Web 技术。
- 互操作性:几乎所有带有显示屏的设备——无论是 ATM 机、车载信息娱乐系统、智能电视、冰箱还是任天堂 Switch——都具备显示 Web 技术的方法。
- 普遍性:很容易找到具有 Web 技术开发经验的开发者
工作流程
特点
使用electron-vite初始化项目
官网: cn-evite.netlify.app/guide/
使用electron-vite初始化项目,可以帮助你快速搭建一个electron-react或electron-vue等项目
npm create @quick-start/electron
组件库选用的antd,如果用最新的antd版本,node环境要求16+
Electron 的生命周期
-
ready:app初始化完成(createWindow)
-
dom-ready:一个窗口中的文本加载完成,后续可以操作dom了
-
did-finsh-load:导航完成时触发,发生在dom-ready之后
-
window-all-closed:所有窗口都被关闭时触发,如果没有监听这个事件,窗口关闭时应用程序会Electron会默认进行退出操作,如果监听了,就需要我们自己需要将当前应该退出(befor-quit,will-quit,quit)
-
befor-quit:在关闭窗口之前触发(没有监听windo-all-closed时,quit就会被触发)
-
will-quit:在窗口关闭并且应用退出时触发
-
quit:当所有窗口被关闭时触发
-
closed:当窗口关闭时触发,此时应删除窗口引用
Electron API
详情参见:electron文档
从主进程到渲染进程的异步通信(IPC模块通信)
ipcMain模块 是一个 EventEmitter 的实例。 当在主进程中使用时,它处理从渲染器进程(网页)发送出来的异步和同步信息。 从渲染器进程发送的消息将被发送到该模块,也可以从主进程向渲染进程发送消息。
- invoke会返回一个Promise(electron7.0+)
// 在主进程中main/index.js
const { ipcMain } = require('electron')
// 监听渲染进程发送的 'request-data' 消息
ipcMain.handle('request-data', (event, arg) => {
console.log('Received request for data:', arg); // Received request for data: aaa
// 模拟异步操作,例如从文件或数据库中获取数据
const data = new Promise((resolve) => {
setTimeout(() => {
resolve({ message: 'Hello from main process!' });
}, 1000);
});
return data;
});
// preload
import { contextBridge, ipcRenderer } from 'electron'
const invokeRequesData = async() => {
const data = await ipcRenderer.invoke('request-data', 'aaa');
return data
}
const api = {
invokeRequesData
}
// 往全局上挂载对应的方法
if (process.contextIsolated) {
try {
contextBridge.exposeInMainWorld('api', api)
} catch (error) {
console.error(error)
}
} else {
window.api = api
}
// 在渲染进程中
export default () => {
const hanleRequest = async () => {
const res = await window.api.invokeRequesData()
console.log(res) // message: 'Hello from main process!'
}
return (
<Button onClick={hanleRequest}>button</Button>
)
}
- send从渲染进程向主进程发布异步消息,无返回值,因为它不等待主进程的响应
// 在主进程中main/index.js
const { ipcMain } = require('electron')
ipcMain.on('watch', (event, params) => {
console.log('输出', event, params)
})
// preload
import { contextBridge, ipcRenderer } from 'electron'
const sendMain = () => {
ipcRenderer.send('watch', 'hello world');
}
const api = {
sendMain,
}
// 往全局上挂载对应的方法
if (process.contextIsolated) {
try {
contextBridge.exposeInMainWorld('api', api)
} catch (error) {
console.error(error)
}
} else {
window.api = api
}
// 在渲染进程中
export default () => {
const handleSendMain = () => {
window.api.sendMain()
}
return (
<Button onClick={handleSendMain}>button</Button>
)
}
- sendSync返回主进程处理后的结果
// 在主进程中main/index.js
const { ipcMain } = require('electron')
// 监听同步消息
ipcMain.on('synchronous-message', (event, arg) => {
console.log('Received synchronous message:', arg);
// 处理逻辑,并返回结果
event.returnValue = 'Synchronous response from main process';
});
const sendSyncMessage = (arg) => {
return ipcRenderer.sendSync('synchronous-message', arg);
}
const api = {
sendSyncMessage
}
// 往全局上挂载对应的方法
if (process.contextIsolated) {
try {
contextBridge.exposeInMainWorld('api', api)
} catch (error) {
console.error(error)
}
} else {
window.api = api
}
// 在渲染进程中
export default () => {
const handleSyncSend = () => {
const res = await window.api.sendSyncMessage()
console.log(res, 'res');
}
return (
<Button onClick={handleSyncSend}>button</Button>
)
}
页面间通信(渲染进程与渲染进程间)
- 通知事件
- 通过主进程转发
- ipcRenderer.sendTo
- 数据共享
- web技术(localStorage,sessionStorage,indexedDB)
- 使用remote
经验与技巧
- 少用remote模块
- 不要用sync模式
- 在请求+响应的通信模式下,需要自定义超时限制
打包
electron-builder 和elecron-forge区别
-
electron-builder:- 更加专注于打包和发布,提供了丰富的配置选项和自动更新功能。
- 适合需要高度自定义打包过程的项目。
-
electron-forge:- 提供了一整套的开发工具链,包括项目初始化、开发调试和打包。
- 适合新项目和需要快速开发的场景。
我们用electron-vite搭建的项目已经配置好了打包命令,执行对应的命令就可以打包对应系统的应用程序了