Electron(01)
Electron
Electron是什么
electron可以使用前端技术开发桌面应用,跨平台性,开发一套应用,可以打包到三个平台。
electron结合Chromium(谷歌内核)和 Node.js 和Native Api
当使用 Electron 时,很重要的一点是要理解 Electron 不是一个 Web 浏览器。 它允许您使用熟悉的 Web 技术构建功能丰富的桌面应用程序
Electron广泛应用
使用Electron框架开发的知名软件。
Visual Studio Code、GithubDesktop、Postman、DockerDesktop...
Electron进程模型
主进程(main.js)。运行在node环境
负责应用的生命周期、展示原生窗口、执行特殊操作和管理渲染进程。
渲染进程(render.js ),运行在浏览器环境
渲染器进程(简称渲染器) 负责展示图形内容。
快速上手
环境安装
node环境(v20.13.1)、npm环境(10.5.2)
测试安装是否成功,按下【win+R】键,输入cmd,打开cmd窗口
输入:node -v // 显示node.js版本
npm -v // 显示npm版本
npm config set registry https://registry.npmmirror.com/
npm i electron -D
main.js
main 文件是 Electron 应用的入口。 这个文件控制 主程序 (main process),它运行在 Node.js 环境里,负责控制您应用的生命周期、显示原生界面、执行特殊操作并管理渲染器进程 (renderer processes)
const { app, BrowserWindow, ipcMain, Notification } = require('electron/main')
const path = require('node:path')
const fs = require('fs')function writeFile(_,data){fs.writeFileSync('D:/hello.txt',data)
}function readFile(){const res = fs.readFileSync('D:/hello.txt').toString();return res
}const createWindow = () => {const win = new BrowserWindow({width: 1000,height: 800,webPreferences: {preload: path.join(__dirname, 'preload.js')}})ipcMain.on('file-save',writeFile)ipcMain.handle('file-read',readFile)win.loadFile('index.html')// 创建并显示通知const notification = new Notification({title: '主进程通知',body: '恭喜你,学会了求雨之术,风来~雨来~'}).show();createWindow.webContents.openDevTools();
}
app.whenReady().then(createWindow)
index.html
1
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';" /><title>简单网页</title>
</head><body><h1>泳哥怎么说!</h1><div class="hint">注意:输入内容,可以保存到d:/hello.txt,点击读取,可以读取该文件内容</div><input id="input" type="text"><button id="btn2">向D盘输入hello.txt</button><br><br><hr><button id="btn3">读取D盘hello.txt</button><script type="text/javascript" src="./render.js"></script>
</body></html>
render.js
const btn2 = document.getElementById('btn2');
const btn3 = document.getElementById('btn3');
const input = document.getElementById('input');btn2.onclick = ()=> {myAPI.saveFile(input.value)
}btn3.onclick = async () => {let data = await myAPI.readFile()alert(data)
}
preload.js
1
const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('myAPI', {saveFile: (data) => {ipcRenderer.send('file-save', data)},readFile: () => {return ipcRenderer.invoke('file-read')}})
进程通信
预加载脚本
preload.js执行时机:预加载脚本在渲染器加载网页之前注入
预加载脚本preload.js(中间人),它在渲染进程运行(浏览器环境),人家也能访问一部分的node api。
如何让你的预加载脚本执行 在main.js 引入预加载脚本,让主进程认识一下预加载脚本
const win = new BrowserWindow({width: 1000,height: 800,webPreferences: {preload: path.join(__dirname, 'preload.js')}})
[渲染进程]调用[主进程] 无返回
需求:比如向d盘的文件写内容
主进程 ipcMain.on,写在app.whenReady().then()中
ipcMain.on('file-save', writeFile)function writeFile(_, data) {fs.writeFileSync('D:/hello.txt', data)
}
ipcRender.send 通过预加载脚本暴露了一个单行的 saveFile函数。
const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('myAPI', {saveFile: (data) => {ipcRenderer.send('file-save', data)}})
最后在渲染器进程,也就是HTML页面就可以使用暴露出来的saveFile方法了
const btn2 = document.getElementById('btn2');
const input = document.getElementById('input');btn2.onclick = ()=> {myAPI.saveFile(input.value)
}
[渲染进程]调用[主进程] 有返回
双向 IPC 的一个常见应用是从渲染器进程码调用代主进程模块并等待结果,更适合请求-响应模式
需求:比如读取d盘的文件内容
主进程 ipcMain.handle,写在app.whenReady().then()中
ipcMain.handle('file-read', readFile)function readFile() {const res = fs.readFileSync('D:/hello.txt').toString();return res
}
ipcRender.invoke 通过预加载脚本暴露了一个单行的 readFile函数。
const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('myAPI', {readFile: () => {return ipcRenderer.invoke('file-read')}})
最后在渲染器进程,也就是HTML页面就可以使用暴露出来的readFile方法了
const btn3 = document.getElementById('btn3');
btn3.onclick = async () => {let data = await myAPI.readFile()alert(data)
}
remote模块
Electron 官方已经明确表示,remote
模块是一个遗留的 API,不建议在新项目中使用。 他们鼓励开发者迁移到 Context Bridge。
remote
模块安全风险: 正如之前提到的,remote
模块允许渲染进程直接访问主进程的几乎所有对象,这带来了严重的安全风险。 恶意代码可能会利用remote
模块来执行任意代码,甚至控制整个应用程序。
替代方案: Context Bridge (结合 ipcRenderer
和 ipcMain
) 提供了更安全、更可控的进程间通信方式。
打包应用
electron-builder
安装打包工具
npm install electron-builder -D
打包应用 electron-builder(做很多自定义的东西)
愉快执行:npm run build,安装包在dist目录,74MB,安装后包含node和chromiun
npm run build
electron-forge
执行打包
npm run make