Electron快速入门——跨平台桌面端应用开发框架
个人简介
👀个人主页: 前端杂货铺
🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🎨100个小功能 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js实战 🍒Three.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧
文章目录
- 前言
- 快速入门 Electron
- Electron 打包
- 写在最后
前言
Electron 是一款应用广泛的 跨平台 的 桌面应用 开发框架(使用 JavaScript、HTML 和 CSS 构建的)。
Electron 本质上是结合了 Chromium 和 Node.js 和 Native API(以二进制形式存在的应用程序开发接口)。
下面,我们开始学习 Elecreon 的基本使用。
快速入门 Electron
首先我们初始化项目,在编译器(如 vscode)的终端键入如下代码。
npm init
一路回车后,即可得到 package.json
文件。
按照 Electron 官方文档的推荐,我们做出以下更改。
- 添加描述信息为
electron test
- 修改主程序入口为
main.js
- 添加应用启动命令
electron .
- 添加作者信息为
zahuopu
{
"name": "electron-test",
"version": "1.0.0",
"description": "electron test",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"author": "zahuopu",
"license": "ISC"
}
做完以上修改后,我们再来安装 Electron。
npm install --save-dev electron
接下来,我们要通过 Electron 实现文件的读写操作(文件结构如下)。
在 pages/index.css
中设置样式。
h1 {
background-color: grey;
color: orange;
}
在 pages/index.html
中引入样式和脚本,并添加一些按钮等信息。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="index.css">
<!-- self 表示仅允许从同源的资源加载;unsafe-inline 表示在HTML文档内使用内联样式;data: 表示允许使用 data: URI来嵌入图像 -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;">
</head>
<body>
<h1>欢迎来到前端杂货铺,我们一起学习 Electron 开发。</h1>
<button id="btn">click me</button>
<hr>
<input id="input" type="text">
<button id="btn2">写入hello.txt</button>
<hr>
<button id="btn3">读取hello.txt</button>
<script src="./render.js"></script>
</body>
</html>
在 main.js
为主进程,该进程在 Node.js 环境中运行。
- 在主进程中我们添加 writeFile(写文件)和 readFile(读文件)的方法。
- 使用 Electron 的 ipcMain 和 ipcRenderer 模块进行进程间通信(IPC)。
- 要将消息从网页发送到主进程,可以使用 ipcMain.handle 设置主进程处理程序,然后公开一个调用 ipcRenderer.invoke 的函数以在预加载脚本中触发处理程序。
Tips:
- on 用于监听事件,当事件发生时执行特定的回调函数。
- handle 用于处理来自渲染进程的异步请求,并返回结果。
// 主进程
// app模块:控制应用的事件生命周期;BrowserWindow模块:用于创建和管理应用窗口。
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const fs = require('fs');
// 写入文件
function writeFile(event, data) {
fs.writeFileSync('./hello.txt', data);
}
// 读取文件
function readFile() {
return fs.readFileSync('./hello.txt').toString();
}
// 将 index.html 加载到新的 BrowserWindow 中
function createWindow() {
const win = new BrowserWindow({
width: 800, // 窗口宽度
height: 600, // 窗口高度
autoHideMenuBar: true, // 隐藏菜单栏
webPreferences: {
preload: path.resolve(__dirname, './preload.js')
}
})
// 注册 file-save 事件,用于写文件
ipcMain.on('file-save', writeFile);
// 设置主进程处理程序 file-read,用于读文件
ipcMain.handle('file-read', readFile);
win.loadFile('./pages/index.html');
}
// 浏览器窗口只能在 app 模块的 ready 事件被触发后创建
app.on('ready', () => {
createWindow();
app.on('activate', () => {
// 当应用被激活时,若没有窗口则创建窗口
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
})
})
// 当所有窗口被关闭时触发
app.on('window-all-closed', () => {
// 不是 macOS,当所有窗口被关闭时退出(macOS关闭所有窗口时程序依旧存在)
if (process.platform !== 'darwin') {
app.quit();
}
})
在 preload.js
预加载脚本中进行通信桥梁的搭建,用于 main.js 主进程 与 render.js 渲染进程的通信。
预加载脚本在网页加载到渲染器之前注入,类似于 Chrome 扩展的 内容脚本。要向渲染器添加需要特权访问的功能,可以通过 contextBridge API 定义 global 对象。
// 预加载脚本
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('myAPI', {
version: process.version,
// 触发主进程中注册的 file-save 事件,写文件
saveFile: (data) => {
ipcRenderer.send('file-save', data);
},
// 触发主进程的处理程序 file-read
readFile() {
return ipcRenderer.invoke('file-read');
}
})
在 render.js
渲染进程中添加鼠标点击事件,触发注册的事件和设置的处理程序。
// 渲染进程
const btn = document.getElementById('btn');
const btn2 = document.getElementById('btn2');
const btn3 = document.getElementById('btn3');
const input = document.getElementById('input');
btn.onclick = () => {
alert(myAPI.version);
}
btn2.onclick = () => {
myAPI.saveFile(input.value);
}
btn3.onclick = async () => {
const data = await myAPI.readFile();
alert(data);
}
之后,在终端键入 npm start
,即可得到窗口。
Electron 打包
electron 打包的方式有多种,经常使用的是借助 electron-builder
进行打包。
在终端键入 npm install electron-builder --save-dev
安装打包插件。
在 package.json 的 scripts 中添加 "build": "electron-builder"
。
"scripts": {
"start": "electron .",
"build": "electron-builder"
},
electron-builder 将会根据我们在 package.json 中的配置来打包应用程序。例如,可以指定打包不同平台的应用程序:
"build": {
"appId": "com.yourapp.id",
"productName": "YourAppName",
"directories": {
"output": "build"
},
"files": [
"dist/**/*",
"node_modules/**/*",
"main.js",
"index.html",
"package.json"
],
"win": {
"target": "nsis"
},
"mac": {
"target": "dmg"
},
"linux": {
"target": [
"AppImage",
"deb"
]
}
}
之后终端键入 npm run build
即可完成打包(ps:打包速度受硬件配置和网络的影响,有时可能需要科学上网才能成功打包)。
我使用 mac 打包成功后得到了如下的 dist 文件,打开 MacOS 文件夹下的可执行程序即可启动。
令人震惊的是打包出来的应用体积竟然高达 236.3MB(仅写了不到100行代码)。
写在最后
Electron 是一个使用 JavaScript、HTML 和 CSS 构建桌面应用的框架。
其优点是它的跨平台性、简单易上手( 使用 JavaScript、HTML 和 CSS 即可打造)。
其缺点是打包体积过大(毕竟内置了Chromium)、性能一般、安全性一般等。
Electron 在 2013 年上线,十余年的时间也是逐渐健壮起来,尽管现在还有很多令人难以接受的缺点,希望后续的 Electron 在不断的迭代过程中越来越成熟好用吧!
好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!
参考资料:
- Electron 中文网
- 禹神:一小时快速上手Electron,前端Electron开发教程