Part5.泛端开发趣闻:Electron 桌面应用开发概述(5/5)

Electron 运行结构剖析

Electron 是一个用于构建跨平台桌面应用程序的开源框架,它结合了 Chromium 和 Node.js,使得开发者能够使用 Web 技术(如 HTML、CSS 和 JavaScript)来开发桌面应用。下面是对 Electron 运行时的基本结构分析。

Electron 运行时的基本结构

  1. 主进程 (Main Process)

    • 定义:主进程是 Electron 应用的入口,负责管理应用的生命周期、创建和管理渲染进程、处理系统事件等。

    • 功能

      • 创建窗口:通过 BrowserWindow 类来创建应用的窗口。
      • 与系统交互:通过 Node.js 的 API 进行文件操作、网络请求等。
      • 处理应用的全局事件,例如启动、退出、显示通知等。
    • 代码示例

      const { app, BrowserWindow } = require('electron');
      
      let mainWindow;
      
      function createWindow() {
          mainWindow = new BrowserWindow({
              width: 800,
              height: 600,
              webPreferences: {
                  nodeIntegration: true, // 允许在渲染进程中使用 Node.js
                  contextIsolation: false // 关闭上下文隔离
              }
          });
      
          mainWindow.loadFile('index.html'); // 加载 HTML 文件
      
          mainWindow.on('closed', function () {
              mainWindow = null; // 当窗口被关闭后,清空引用
          });
      }
      
      app.on('ready', createWindow); // 应用准备好时创建窗口
      
      app.on('window-all-closed', function () {
          if (process.platform !== 'darwin') {
              app.quit(); // 在 macOS 上,窗口关闭后不退出应用
          }
      });
      
  2. 渲染进程 (Renderer Process)

    • 定义:每个 BrowserWindow 创建一个渲染进程,负责渲染应用的 UI 和处理用户交互。

    • 功能

      • 运行 Web 内容:渲染和显示 HTML、CSS、JavaScript。
      • 与主进程通信:通过 ipcRenderer 模块与主进程进行通信,实现功能间的协作。
    • 代码示例

      const { ipcRenderer } = require('electron');
      
      // 发送消息到主进程
      ipcRenderer.send('asynchronous-message', 'ping');
      
      // 监听来自主进程的消息
      ipcRenderer.on('asynchronous-reply', (event, arg) => {
          console.log(arg); // 打印来自主进程的回复
      });
      
  3. ** IPC (Inter-Process Communication)**:

    • 定义:用于主进程和渲染进程之间的通信。

    • 功能

      • ipcMain: 在主进程中使用来接收 ipcRenderer 发送的消息。
      • ipcRenderer: 在渲染进程中使用来发送消息给主进程。
    • 消息传递示例

      // 主进程(main.js)
      const { ipcMain } = require('electron');
      
      ipcMain.on('asynchronous-message', (event, arg) => {
          console.log(arg); // 打印收到的消息
          event.reply('asynchronous-reply', 'pong'); // 发送回复
      });
      
  4. 资源与文件结构

    • HTML/CSS/JavaScript:开发者使用这些 Web 技术创建用户界面。
    • 静态资源:图像、字体等静态文件。

Electron 运行时的关键特性

  • 跨平台:Electron 支持 Windows、macOS 和 Linux,使得应用可以在多个操作系统上运行。
  • Node.js 集成:开发者可以使用 Node.js 的 API,这使得桌面应用能够进行文件读写、网络请求等操作。
  • 强大的插件生态:Electron 提供了很多第三方库和插件,帮助开发者实现各种功能,如自动更新、打包安装等。
  • Web 技术:使用 HTML、CSS 和 JavaScript 让 Web 开发者能快速上手,降低了桌面应用开发的门槛。

总结

Electron 的基本结构是由主进程和渲染进程组成的,主进程负责管理应用生命周期和窗口,渲染进程负责用户界面的渲染和交互。这种结构使得 Electron 应用能够灵活地使用 Web 技术,同时结合 Node.js 的强大功能,构建丰富的桌面应用程序。

Electron 快速入门:API 与基础案例

下面是关于 Electron 的快速上手指南,常用 API 以及一个基础案例的详细介绍。

一、快速上手

1. 环境准备

首先,确保你已经安装了 Node.js 和 npm(Node 包管理器)。你可以通过以下命令检查是否安装:

node -v
npm -v

如果没有安装,可以从 Node.js 官网 下载并安装。

2. 创建一个新的 Electron 项目

在终端中运行以下命令来创建新的文件夹并进入该文件夹:

mkdir my-electron-app
cd my-electron-app

接下来,初始化一个新的 npm 项目:

npm init -y

安装 Electron:

npm install electron --save-dev

3. 项目结构

创建一个基本的项目结构:

my-electron-app/
├── package.json
├── main.js          # 主进程文件
└── index.html       # 渲染进程文件

二、基础案例

1. 编写 main.js

main.js 中添加以下代码来设置主进程:

const { app, BrowserWindow } = require('electron');

let mainWindow;

function createWindow() {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true, // 允许在渲染进程中使用 Node.js
            contextIsolation: false // 关闭上下文隔离
        }
    });

    mainWindow.loadFile('index.html'); // 加载 HTML 文件

    // 关闭窗口时清空引用
    mainWindow.on('closed', function () {
        mainWindow = null;
    });
}

app.on('ready', createWindow); // 应用准备好时创建窗口

app.on('window-all-closed', function () {
    if (process.platform !== 'darwin') {
        app.quit(); // 在 macOS 上,窗口关闭后不退出应用
    }
});

app.on('activate', function () {
    if (mainWindow === null) {
        createWindow(); // 点击图标时重新创建窗口
    }
});

2. 编写 index.html

index.html 中添加基本的 HTML 内容:

<!DOCTYPE html>
<html>
<head>
    <title>My Electron App</title>
</head>
<body>
    <h1>Hello, Electron!</h1>
    <p>This is a simple Electron application.</p>
</body>
</html>

3. 更新 package.json

package.json 中添加 start 脚本以便方便启动 Electron 应用:

{
  "name": "my-electron-app",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  ...
}

4. 启动应用

在终端中运行以下命令来启动 Electron 应用:

npm start

你应该能看到一个简单的窗口,里面显示“Hello, Electron!”的消息。

三、常用 API

以下是一些 Electron 中的常用 API:

  1. BrowserWindow:用于创建和控制应用窗口。

    const { BrowserWindow } = require('electron');
    let win = new BrowserWindow({ width: 800, height: 600 });
    
  2. ipcMainipcRenderer:用于主进程与渲染进程之间的通信。

    // 主进程
    const { ipcMain } = require('electron');
    ipcMain.on('message', (event, arg) => {
        console.log(arg); // 打印收到的消息
    });
    
    // 渲染进程
    const { ipcRenderer } = require('electron');
    ipcRenderer.send('message', 'Hello from renderer!');
    
  3. Menu:用于创建应用菜单。

    const { Menu } = require('electron');
    const template = [{
        label: 'File',
        submenu: [{ role: 'quit' }]
    }];
    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
    
  4. Dialog:用于创建对话框,如打开文件、保存文件等。

    const { dialog } = require('electron');
    dialog.showOpenDialog({ properties: ['openFile', 'openDirectory'] })
        .then(result => {
            console.log(result.canceled);
            console.log(result.filePaths);
        }).catch(err => {
            console.log(err);
        });
    

四、总结

你现在已经学习了如何快速上手 Electron,包括环境准备、创建基本应用、常用 API 的使用,以及自定义主进程与渲染进程之间的消息传递。通过这个案例,你可以进一步熟悉 Electron 的基本用法,进而开发出更加复杂的桌面应用。

Electron 进程通信:主进程与渲染进程

在 Electron 中,主进程和渲染进程是两个重要的概念,它们在应用的架构中承担着不同的角色,并且通过 IPC (进程间通信) 来相互通信。下面将详细介绍它们之间的差异及通信方式。

一、主进程与渲染进程的差异

1. 主进程 (Main Process)

  • 定义:应用的入口,通过 main.js 文件启动。主进程管理应用的生命周期、窗口创建以及应用与操作系统的交互。
  • 职责
    • 启动和关闭应用。
    • 管理窗口(BrowserWindow)。
    • 处理菜单、对话框和系统级事件。
    • 可以直接使用 Node.js API,包括文件系统的操作、网络请求等。
  • 性能:主进程是单线程的,处理所有的 GUI 相关操作,同时也负责其他所有电子事件。

2. 渲染进程 (Renderer Process)

  • 定义:每个 BrowserWindow 实例都会创建一个渲染进程,主要负责渲染 UI 和处理用户输入。
  • 职责
    • 加载和呈现 HTML、CSS 和 JavaScript。
    • 响应用户的交互(如点击、输入等)。
    • 可以通过 ipcRenderer 与主进程进行通信。
  • 安全性:渲染进程相对独立,具有更高的安全性。如果渲染进程崩溃,不会影响到主进程。

二、主进程与渲染进程之间的相互通信

主进程与渲染进程之间无法直接调用对方的函数,而是通过 IPC 来进行通信。以下是具体的通信方式。

1. 使用 ipcMainipcRenderer

  • ipcMain:在主进程中使用的模块,用于接收来自渲染进程的消息。
  • ipcRenderer:在渲染进程中使用的模块,用于发送消息到主进程。

2. 发送异步消息

例子

主进程代码 (main.js):

const { app, BrowserWindow, ipcMain } = require('electron');

let mainWindow;

function createWindow() {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false, // 注意:在 production 中建议启用
        }
    });

    mainWindow.loadFile('index.html');

    // 监听来自渲染进程的异步消息
    ipcMain.on('asynchronous-message', (event, arg) => {
        console.log(arg); // 打印渲染进程发送的消息
        // 发送回复回渲染进程
        event.reply('asynchronous-reply', 'pong');
    });
}

app.on('ready', createWindow);

渲染进程代码 (index.html):

<!DOCTYPE html>
<html>
<head>
    <title>IPC Example</title>
    <script>
        const { ipcRenderer } = require('electron');

        function sendMessage() {
            ipcRenderer.send('asynchronous-message', 'ping');
        }

        ipcRenderer.on('asynchronous-reply', (event, arg) => {
            console.log(arg); // 打印来自主进程的回复消息
            document.getElementById('response').innerText = arg; // 显示回复
        });
    </script>
</head>
<body>
    <h1>IPC Example</h1>
    <button onclick="sendMessage()">发送消息</button>
    <p>主进程回复: <span id="response"></span></p>
</body>
</html>

3. 发送同步消息

尽量避免使用同步消息,因为它会阻塞主进程。若需要使用,可以使用 ipcMain.handleipcRenderer.invoke

主进程代码 (main.js):

const { ipcMain } = require('electron');

ipcMain.handle('synchronous-message', (event, arg) => {
    console.log(arg); // 打印渲染进程发送的消息
    return 'synchronous reply'; // 返回同步回复
});

渲染进程代码 (index.html):

async function sendSyncMessage() {
    const response = await ipcRenderer.invoke('synchronous-message', 'ping');
    console.log(response); // 打印来自主进程的同步回复
}

三、总结

  • 主进程 负责管理应用的生命周期和系统级事件,而 渲染进程 负责渲染 UI 和处理用户交互。
  • 主进程与渲染进程之间无法直接调用对方的函数,必须通过 IPC 进行消息的发送和接收。
  • 使用 ipcMainipcRenderer 实现异步和同步消息传递,进行数据的交互。异步消息适合大多数场景,而同步消息应谨慎使用,以避免阻塞主进程。

这种设计模式有效地将应用的逻辑与界面分开,增强了安全性和稳定性。希望这些信息能帮助你更好地理解 Electron 的主进程与渲染进程之间的关系与通信方式!

桌面应用功能实现:基于 Electron

常见桌面应用程序的功能实现通常涉及多个方面,包括用户界面(UI),数据存储,网络请求和进程间通信等。以下是一些常见桌面应用的功能实现示例,以及它们在 Electron 中的实现思路。

1. 窗口管理

实现需求:创建、关闭、最小化、最大化多个窗口。

思路

  • 使用 BrowserWindow 来创建窗口。
  • 可以设置窗口属性,比如大小、标题、菜单等。

示例代码

const { app, BrowserWindow } = require('electron');

function createWindow() {
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
        }
    });

    mainWindow.loadFile('index.html');

    // 可以添加其他窗口管理功能
}

app.whenReady().then(createWindow);

2. 文件操作

实现需求:打开、保存文件,读取和写入数据。

思路

  • 使用 Node.js 的 fs 模块来实现文件读写。
  • 提供文件对话框供用户选择文件。

示例代码

const { dialog } = require('electron').remote;
const fs = require('fs');

function openFile() {
    dialog.showOpenDialog({
        properties: ['openFile']
    }).then(result => {
        const filePath = result.filePaths[0];
        fs.readFile(filePath, 'utf-8', (err, data) => {
            if (err) throw err;
            console.log(data); // 处理文件内容
        });
    }).catch(err => {
        console.log(err);
    });
}

function saveFile(content) {
    dialog.showSaveDialog().then(result => {
        const filePath = result.filePath;
        fs.writeFile(filePath, content, err => {
            if (err) throw err;
            console.log('文件已保存!');
        });
    });
}

3. 数据存储

实现需求:存储用户偏好设置和应用数据。

思路

  • 使用 JSON 文件或者 SQLite 数据库来存储数据。
  • 使用 Electron 的 localStorageelectron-store 等模块进行简单的数据存储。

示例代码(使用 electron-store):

npm install electron-store
const Store = require('electron-store');
const store = new Store();

// 保存数据
store.set('userPreferences', { theme: 'dark', fontSize: 14 });

// 读取数据
const userPreferences = store.get('userPreferences');
console.log(userPreferences);

4. 通知功能

实现需求:向用户发送系统通知。

思路

  • 使用 Electron 的 Notification API。

示例代码

const { Notification } = require('electron');

function showNotification() {
    const notification = new Notification({
        title: '提醒',
        body: '您有新的消息!'
    });

    notification.show();
}

5. 网络请求

实现需求:从服务器获取数据,提交表单等。

思路

  • 使用 Node.js 提供的 httphttps 模块,或者使用更方便的 axios 库进行 API 请求。

示例代码(使用 axios):

npm install axios
const axios = require('axios');

function fetchData() {
    axios.get('https://api.example.com/data')
        .t

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

前端求职突破计划 文章被收录于专栏

你是否渴望全面提升前端技能?本专栏将带你畅游前端世界!从 JS 深析趣谈,让你领略 JavaScript 的独特魅力;到前端工程漫话,掌握项目构建精髓。深入洞察框架原理,探索 Node 全栈开发。泛端开发趣闻,开启多端应用新视野;揭秘商业解方奥秘,把握行业趋势。高阶专题层层剖析,助你突破技术瓶颈。更有前端面试指南,为求职保驾护航。无论你是新手小白还是资深开发者,这里都有你需要的知识盛宴!

全部评论
Electron 是一个用于构建跨平台桌面应用程序的开源框架,它结合了 Chromium 和 Node.js,使得开发者能够使用 Web 技术(如 HTML、CSS 和 JavaScript)来开发桌面应用。
点赞 回复 分享
发布于 02-22 11:47 广东

相关推荐

06-10 23:36
已编辑
首都经济贸易大学 C++
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务