Electron快速入门——跨平台桌面端应用开发框架

个人简介

👀个人主页: 前端杂货铺

🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展

📃个人状态: 研发工程师,现效力于中国工业软件事业

🚀人生格言: 积跬步至千里,积小流成江海

🥇推荐学习:🍍前端面试宝典 🎨100个小功能 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js实战 🍒Three.js

🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

文章目录

    • 前言
    • [快速入门 Electron](#快速入门 Electron)
    • [Electron 打包](#Electron 打包)
    • 写在最后

前言

Electron 是一款应用广泛的 跨平台桌面应用 开发框架(使用 JavaScript、HTML 和 CSS 构建的)。

Electron 本质上是结合了 Chromium 和 Node.js 和 Native API(以二进制形式存在的应用程序开发接口)。

下面,我们开始学习 Elecreon 的基本使用。


快速入门 Electron

首先我们初始化项目,在编译器(如 vscode)的终端键入如下代码。

clike 复制代码
npm init

一路回车后,即可得到 package.json 文件。

按照 Electron 官方文档的推荐,我们做出以下更改。

  • 添加描述信息为 electron test
  • 修改主程序入口为 main.js
  • 添加应用启动命令 electron .
  • 添加作者信息为 zahuopu
clike 复制代码
{
  "name": "electron-test",
  "version": "1.0.0",
  "description": "electron test",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "author": "zahuopu",
  "license": "ISC"
}

做完以上修改后,我们再来安装 Electron。

clike 复制代码
npm install --save-dev electron

接下来,我们要通过 Electron 实现文件的读写操作(文件结构如下)。

pages/index.css 中设置样式。

clike 复制代码
h1 {
    background-color: grey;
    color: orange;
}

pages/index.html 中引入样式和脚本,并添加一些按钮等信息。

clike 复制代码
<!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:

  1. on 用于监听事件,当事件发生时执行特定的回调函数。
  2. handle 用于处理来自渲染进程的异步请求,并返回结果。
javascript 复制代码
// 主进程
// 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 对象。

javascript 复制代码
// 预加载脚本
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 渲染进程中添加鼠标点击事件,触发注册的事件和设置的处理程序。

javascript 复制代码
// 渲染进程
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"

javascript 复制代码
"scripts": {
  "start": "electron .",
  "build": "electron-builder"
},

electron-builder 将会根据我们在 package.json 中的配置来打包应用程序。例如,可以指定打包不同平台的应用程序:

javascript 复制代码
"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 在不断的迭代过程中越来越成熟好用吧!

好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!


参考资料:

  1. Electron 中文网
  2. 禹神:一小时快速上手Electron,前端Electron开发教程


相关推荐
passerby606130 分钟前
完成前端时间处理的另一块版图
前端·github·web components
掘了38 分钟前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅41 分钟前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
Cobyte2 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc