当前位置: 首页 > news >正文

Electron 主进程与渲染进程、预加载preload.js

在 Electron 中,主要控制两类进程: 主进程渲染进程

Electron 应⽤的结构如下图:
在这里插入图片描述
如果需要更深入的了解electron进程,可以访问官网 流程模型 文档。

主进程

  • 每个 Electron 应用都有一个单一的主进程,作为应用程序的入口点(主进程具有唯一性)。任何 Electron 应用程序的入口都是 main 文件,负责控制应用的生命周期、创建和管理窗口、与操作系统进行交互等。
  • 主进程在 Node.js 环境中运行,它具有 require 模块和使⽤所有 Node.js API 的能力。
  • 主进程的核心:使用 BrowserWindow 来创建和管理应用程序窗口。

main.js 中,打印:

console.log(__dirname)
console.log('node版本:', process.versions.node)
console.log('chrome版本:', process.versions.chrome)
console.log('electron版本:', process.versions.electron)

在终端中输入结果如下:
在这里插入图片描述

注意:在主进程中执行的console.log()语句,都在vs code 的终端中输出,不会在electron 应用中打印。

main.js 中,打印 window

console.log(window)

报错:window is not defined…
在这里插入图片描述

渲染进程

每个 Electron 应用都会为每个打开的 BrowserWindow ( 与每个网页嵌入 ) 生成一个单独的渲染器进程。 洽如其名,渲染器负责 渲染 网页内容。

  • 每个 BrowserWindow 实例都对应⼀个单独的渲染进程。
  • 一个 Electron 窗口可以包含一个或多个渲染进程,每个渲染进程负责渲染网页内容并执行网页中的 JavaScript 代码。(关系类似于 浏览器、浏览器中的标签页)
  • 运行在渲染器进程中的代码,必须遵守网页标准。这意味着 渲染进程无权直接访问 require 或 使用 任何 Node.js API。
  • 渲染进程主要负责呈现用户界面、响应用户交互、执行网页中的业务逻辑等。

pages/index.html 中:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><metahttp-equiv="Content-Security-Policy"content="default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;"/><title>Hello Electron!</title></head><body><h1>Hello Electron!</h1>We are using Node.js <span id="node-version"></span>, Chromium<span id="chrome-version"></span>, and Electron<span id="electron-version"></span>.</body><script src="./render.js"></script>
</html>

pages/render.js 中:

console.log(window)
console.log(process)

在应用窗口中查看打印结果:
在这里插入图片描述

window能成功打印,console.log(process)报错:process is not defined…

pages/render.js 中,不能访问 Node.js API。那么,该如何实现在index.html中展示chrome、node、electron的版本呢?

处于渲染器进程的用户界面,该怎样才与 Node.js 和 Electron 的原生桌面功能进行交互?


通过预加载脚本从渲染器访问Node.js


预加载(preload)脚本在 Electron 应用中起着重要的桥梁作用,它允许渲染进程安全地与主进程进行交互,同时增强了应用的安全性和性能。

预加载(preload)脚本在渲染器进程加载之前加载,并有权访问两个 渲染器全局 (例如 windowdocument) 和 Node.js 环境。

预加载(preload)脚本是运行在渲染器进程中的,但它是在网页内容加载之前执行的。 这意味着它具有比普通渲染器更高的权限,可以访问 Node.js API ,同时也可以与网页内容进行更安全的交互。

创建一个名为 preload.js 的新脚本如下:

// contextBridge:在隔离的上下文中创建一个安全的、双向的、同步的桥梁。
const {contextBridge} = require('electron')// 暴露数据给渲染进程
contextBridge.exposeInMainWorld('aaaAPI', {version: process.version,versions: process.versions,num: 666
})

在主线程中引⼊ preload.js

const { app, BrowserWindow } = require('electron')
// 导入 Node.js 的 path 模块
const path = require('node:path')// 修改已有的 createWindow() 方法
function createWindow() {const win = new BrowserWindow({width: 500, // 窗口宽度height: 300, // 窗口高度autoHideMenuBar: true, // 隐藏菜单栏webPreferences: {// 此处只能使用绝对路径preload: path.join(__dirname, 'preload.js')}});// 在窗口中加载一个远程页面win.loadFile('./pages/index.html');
}

执行npm start,启动应用,打开应用的控制台。
可以看到pages/render.js打印的window
在这里插入图片描述

完善pages/render.js,在渲染进程中使用versions,实现在 pages/index.html 页面展示版本信息:

let nodeDom = document.getElementById('node-version')
let chromeDom = document.getElementById('chrome-version')
let electronDom = document.getElementById('electron-version')const { node, chrome, electron } = aaaAPI.versionsnodeDom.innerHTML = node
chromeDom.innerHTML = chrome
electronDom.innerHTML = electron

查看应用窗口渲染结果:
在这里插入图片描述


现在,项目的目录结构如下图所示:
在这里插入图片描述
注意: 预加载(preload)脚本只能访问部分 Node.js API,但是主进程可以访问全部API。此时,需要使用进程通信。

相关文章:

  • STM32F1+HAL库+FreeTOTS学习14——数值信号量
  • 【Go】-Websocket的使用
  • ThinkPHP一对多的关联模型运用
  • ClickHouse | 入门
  • 2024 年实验室设备管理系统的选择指南
  • 第四章-课后练习5:修正指数曲线模型——excel和python应用(2)
  • 力扣 简单 104.二叉树的最大深度
  • Llama 系列简介与 Llama3 预训练模型推理
  • springboot实战学习(9)(配置mybatis“驼峰命名“和“下划线命名“自动转换)(postman接口测试统一添加请求头)(获取用户详细信息接口)
  • 【数据治理-设计数据标准】
  • py-mmcif包pdbx_struct_assembly对象介绍
  • 困扰我们的,不是如何过上更幸福的生活,而是如何过上比别人更幸福的生活
  • Linux之实战命令18:col应用实例(五十二)
  • 开启争对目标检测的100类数据集-信息收集
  • 深入理解 Nuxt.js 中的 app:data:refresh 钩子
  • 【Leetcode】101. 对称二叉树
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • Angularjs之国际化
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • Hexo+码云+git快速搭建免费的静态Blog
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • JavaScript设计模式系列一:工厂模式
  • mongo索引构建
  • PHP的类修饰符与访问修饰符
  • Vue官网教程学习过程中值得记录的一些事情
  • 程序员最讨厌的9句话,你可有补充?
  • 机器学习学习笔记一
  • 聚簇索引和非聚簇索引
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (十三)Maven插件解析运行机制
  • (学习总结)STM32CubeMX HAL库 学习笔记撰写心得
  • (转)人的集合论——移山之道
  • (转)重识new
  • **python多态
  • .cfg\.dat\.mak(持续补充)
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET gRPC 和RESTful简单对比
  • .NET 服务 ServiceController
  • .Net 垃圾回收机制原理(二)
  • .NET8使用VS2022打包Docker镜像
  • .sh
  • @SpringBootConfiguration重复加载报错
  • @Transactional 竟也能解决分布式事务?
  • [2024最新教程]地表最强AGI:Claude 3注册账号/登录账号/访问方法,小白教程包教包会
  • [BZOJ4554][TJOI2016HEOI2016]游戏(匈牙利)
  • [C\C++]读入优化【技巧】