Electron入门笔记

Electron入门笔记

  • Electron
    • Electron 是什么
    • Electron流程模型
    • 创建第一个Electron项目
    • 配置自动重启
    • 主进程和渲染进程通信
    • 打包应用

Electron

Electron 是什么

  • 跨平台的桌面应用开发框架
  • 使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium和 Node.js

Electron流程模型

  • 主进程:

    • 主进程只有一个
    • 主要功能是管理渲染进程,与操作系统打交道。调用Native API 进行各种系统级的操作,并且可以跨平台
    • node环境,能使用node的各种API,使用node的各个模块进行操作,没有浏览器相关的属性,无法访问window等浏览器属性
      在这里插入图片描述
      渲染进程:
  • 渲染进程有多个

  • 主要是程序的展示的窗口

  • 浏览器环境,本质就是Chromium,能使用浏览器的各种API,无法使用node环境的API(ctrl shift i可以打开窗口的控制台,跟浏览器是一模一样的,ctrl R可以刷新页面)
    在这里插入图片描述

  • 主进程和渲染进程是可以通信的,可以是渲染进程向主进程单向通信,也可以是主进程想渲染进程通信,也可以双向通信,进程间的通信称为IPC

  • 总结:主进程(一个)管理各个渲染进程(多个),渲染进程跟主进程进行通信(渲染进程间无法直接通信,通过主进程作为中间人可以实现),主进程调用各种Native API 完成系统级操作

创建第一个Electron项目

  • 环境:需要先安装Node.js

    • 注意:先安装Node.js只是为了正确安装electron, 因为 Electron 将 Node.js 嵌入到其二进制文件中,你应用运行时的 Node.js 版本与你系统中运行的 Node.js 版本无关
  • mkdir my-electron-app && cd my-electron-app
    yarn init
    
  • 执行yarn init生成package.jsonauthordescription在打包阶段属于必填项

  • {"name": "electron-first","version": "1.0.0","main": "main.js","license": "MIT","author": "XiaoMing","description": "Hello World",
    }
  • 安装Electron并在package.json配置启动命令

    • yarn add ELectron -D
      
    • {"scripts": {"start": "electron ." // 注意 . 不能省略}
      }
      
    • 启动项目前需要创建主进程,也就是package.json中对应的main,命名为main.js, 否则会报错,创建完成后,执行yarn start即可启动

    • 此时启动无报错,但也无任何反应,因为没有在主进程里配置任何东西,渲染窗口等进程需要在主进程中配置

  • 创建pages文件夹用于存放页面文件(也就是渲染进程的文件),分别创建对应的index.html,index.css,render.js文件

    • index.html中引入cssjs文件

    • htmlhead需要配置一个meta,解决CSP的警官

      • <metahttp-equiv="Content-Security-Policy"content="default-src 'self'; script-src 'self' 'unsafe-inline'"
        />
        

在这里插入图片描述

      • default-src 'self'是一组配置,意思是如果不做出任何的说明,引入的外部资源,只能是属于同源
        script-src 'self' 'unsafe-inline'是另一组配置,指引入样式的时候,可以有两种写法,第一种写法
        self 是可以引入同源的样式表,第二种写法unsafe-inline 可以使用行内样式
  • <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP --><metahttp-equiv="Content-Security-Policy"content="default-src 'self'; script-src 'self' 'unsafe-inline'"/><title>Hello World!</title><link rel="stylesheet" href="./index.css" /></head><body><h1>Hello World!</h1>We are using Node.js <span id="node-version"></span>, Chromium<span id="chrome-version"></span>, and Electron<span id="electron-version"></span>.<script src="./render.js"></script></body>
    </html>

在这里插入图片描述
需要将写好的页面加载出来,如何加载页面,这个需要主进程进行控制,因此需要配置主进程main.js

  • const { app, BrowserWindow } = require("electron");const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600,});win.loadFile("./pages/index.html");
    };// app.whenReady().then(() => {}) 的写法与 app.on("ready", () =>{}) 同理app.on("ready", () => {createWindow();app.on("window-all-closed", () => {if (process.platform !== "darwin") app.quit();});
    });
    

在这里插入图片描述

  • 管理窗口的生命周期

    • 关闭所有窗口时退出应用 (Windows & Linux),在Windows和Linux上,关闭所有窗口通常会完全退出一个应用程序。

      // 为了实现这一点,你需要监听 app 模块的 'window-all-closed' 事件。如果用户不是在 macOS(darwin) 上运行程序,则调用 app.quit()。
      app.on('window-all-closed', () => {if (process.platform !== 'darwin') app.quit()
      })
      
    • 如果没有窗口打开则打开一个窗口 (macOS),macOS 应用通常即使在没有打开任何窗口的情况下也继续运行,并且在没有窗口可用的情况下激活应用时会打开新的窗口。

      // 为了实现这一特性,监听 app 模块的 activate 事件。如果没有任何浏览器窗口是打开的,则调用 createWindow() 方法。
      // 因为窗口无法在 ready 事件前创建,你应当在你的应用初始化后仅监听 activate 事件。 通过在您现有的 whenReady() 回调中附上您的事件监听器来完成这个操作。app.on("ready", () => {createWindow();app.on('activate', () => {if (BrowserWindow.getAllWindows().length === 0) createWindow()})
      });
      
  • 完整项目结构
    在这里插入图片描述

  • 启动项目yarn start
    在这里插入图片描述

配置自动重启

  • 主进程每修改一次就得手动重启一次,可以配置自动重启

  • 安装nodemon

    • yarn add nodemon -D
      
  • 更改启动命令

    • {"scripts": {"start": " nodemon --exec electron ."},
      }
      
  • 更改完启动命令发现自动重启的是主进程,但不改主进程,只改页面,发现页面窗口是需要手动刷新的,配置一个nodemon.json即可实现页面文件也能自动刷新

    • {"ignore": ["node_modules", "dist"],"restartable": "r","watch": ["*.*"],"ext": "html, css, js"
      }

主进程和渲染进程通信

  • 目前主进程和渲染进程是没有什么关联的,主进程只是配置了加载渲染进程,然后他们之前没有其他的关系了,此时如果需要在渲染进程里拿到主进程中的node版本号是不可行的,因为渲染进程是浏览器环境,没有process属性

  • 此时就需要一个预加载脚本作为主进程和渲染进程之间通信的桥梁,注意:预加载脚本可以拿到部分的node API,但不是所有

  • 主进程目录下创建preload.js

    • const { contextBridge } = require("electron");contextBridge.exposeInMainWorld("api", {version: process.version,
      });
      

在这里插入图片描述

  • 主进程需要配置运行预加载脚本

    • const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: path.resolve(__dirname, "./preload.js"),},});win.loadFile("./pages/index.html");
      };
      

在这里插入图片描述

  • 配置一下渲染进程的脚本

    • const nodeVersion = document.querySelector("#node-version");console.log(window);nodeVersion.textContent = api.version;
  • 最后结果
    在这里插入图片描述

  • 由此,引出,渲染进程跟主进程之间的相互通信,需要通过预加载脚本,因为预加载脚本也只能访问到node部分属性,像是文件操作等还是需要主进程来完成的

  • 完成在窗口输入内容,并写入文件,最近将文件读出来的需求即可完全理解进程间的通信
    在这里插入图片描述

  • main.js

    • const { app, BrowserWindow, ipcMain } = require("electron");
      const path = require("path");
      const fs = require("fs");const writeFile = (_, data) => {fs.writeFileSync(path.resolve(__dirname, "./hello.txt"), data);
      };const readFile = () => {return fs.readFileSync(path.resolve(__dirname, "./hello.txt")).toString();
      };const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: path.resolve(__dirname, "./preload.js"),},});ipcMain.on("write-file", writeFile);ipcMain.handle("read-file", readFile);win.loadFile("./pages/index.html");
      };app.on("ready", () => {createWindow();app.on("activate", () => {if (BrowserWindow.getAllWindows().length === 0) createWindow();});
      });app.on("window-all-closed", () => {if (process.platform !== "darwin") app.quit();
      });
  • preload.js

    • const { contextBridge, ipcRenderer } = require("electron");contextBridge.exposeInMainWorld("api", {version: process.version,writeFile: (data) => {ipcRenderer.send("write-file", data);},readFile: () => ipcRenderer.invoke("read-file"),
      });
  • render.js

    • const nodeVersion = document.querySelector("#node-version");
      const input = document.querySelector("#input");
      const write = document.querySelector("#write");
      const read = document.querySelector("#read");nodeVersion.textContent = api.version;window.onload = () => {write.addEventListener("click", () => {api.writeFile(input.value);});read.addEventListener("click", async () => {const text = await api.readFile();alert(text);});
      };
  • index.html

    • <!DOCTYPE html>
      <html lang="en"><head><meta charset="UTF-8" /><!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP --><metahttp-equiv="Content-Security-Policy"content="default-src 'self'; script-src 'self' 'unsafe-inline'"/><title>Hello World!</title><link rel="stylesheet" href="./index.css" /></head><body><h1>Hello World!</h1>We are using Node.js <span id="node-version"></span>, Chromium<span id="chrome-version"></span>, and Electron<span id="electron-version"></span>.<hr /><input id="input" /><button id="write">写入文件</button><button id="read">读取文件</button><script src="./render.js"></script></body>
      </html>

在这里插入图片描述

打包应用

  • 使用 electron build 打包成一个安装包应用

  • yarn add electron-build -D
    
  • electron-build配置地址:CodeBlog/Electron/electron-builder打包详解.md at master · QDMarkMan/CodeBlog (github.com)

  • 配置package.json

    • {"scripts": {"build": "electron-builder"},"build": {"appId": "com.electron.myapp","nsis": {"oneClick": false,"allowElevation": true,"allowToChangeInstallationDirectory": true},"win": {"icon": "./vite.svg","target": [{"target": "nsis","arch": ["x64"]}]}}
      }
      
  • electron-builder打包慢解决方法

    • electron-builder 打包太慢解决方法build过程耗时较长,可以手动下载部分文件。镜像地址 https:/ - 掘金 (juejin.cn)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/57095.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Print Settings Page 打印设置页面

“打印设置”页面提供了设计时工具&#xff0c;用于自定义控制视图打印版本外观的打印选项。此页面如下图所示。 “选项”和“行为”选项卡式页面提供对视图打印选项的设计时访问&#xff0c;这些选项可通过其 GridView.OptionsPrint 属性或卡片视图的 CardView.OptionsPrint 进…

基于vue框架的的点餐系统1o2te(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,商家,菜品分类,菜品信息 开题报告内容 基于Vue框架的点餐系统开题报告 一、研究背景与意义 随着移动互联网技术的飞速发展&#xff0c;餐饮行业也迎来了数字化转型的浪潮。传统的点餐方式&#xff0c;如纸质菜单和人工记录&…

颐驰06持续交付,明日科技赋能出行生活

在全球智能出行领域&#xff0c;自动驾驶技术的发展一直是行业关注的焦点。不久前&#xff0c;特斯拉发布的自动驾驶出租车引发了全球关注&#xff0c;但由于缺乏具体的技术细节&#xff0c;导致投资者信心受挫&#xff0c;特斯拉股票一度下跌近10%。与此同时&#xff0c;中国车…

CTF(四)

导言&#xff1a; 本文主要讲述在CTF竞赛中&#xff0c;web类题目file_include。 靶场链接&#xff1a;攻防世界 (xctf.org.cn) 一&#xff0c;观察页面。 可以看到一段php代码。从则段代码中我们可以知道&#xff1a; 1&#xff0c;使用include引入check.php文件&#xff…

Nodejs使用http模块创建Web服务器接收解析RFID读卡器刷卡数据

本示例使用设备&#xff1a; https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.1d292c1buHvw58&ftt&id22173428704 Javascript源码 //引用http模块创建web服务器&#xff0c;监听指定的端口获取以GET、POST、JSON等方式上传的数据&#xff0c;并回应驱动读卡…

【论文学习与撰写】论文里的Mathtype公式复制粘贴,跨文档复制后错码/错位问题的解决

1、描述 问题&#xff1a;论文的草稿已经写好&#xff0c;里面的公式之类的都已经一个个打上去了 但是把草稿里的正文和公式粘贴在另一个文档里的时候&#xff0c;会出些公式格式错误的情况 那该怎么操作保证复制后的公式保持原格式呢 选中复制的内容&#xff0c;在另一个文…

探索YOLO v11:3D人工智能的RGB-D视觉革命

哈喽&#xff0c;各位OAK中国的朋友们! 大家好我是张伯生 今天&#xff0c;我想给大家演示一下最新发布的Yolo V11神经网络 下面我将演示的一个程序是&#xff1a;同时在我们的OAK相机上跑Yolo V11和RGB-D&#xff0c;也就是彩色相机和深度图的一个叠加的一个效果 RGB-D和Yo…

芯知识 | NVH-FLASH语音芯片支持平台做语音—打造音频IC技术革新

随着科技的飞速发展&#xff0c;人们对于电子产品的音频性能要求越来越高。在这种背景下&#xff0c;NVH-FLASH系列语音芯片应运而生&#xff0c;作为音频IC领域的一次重大技术革新&#xff0c;NVH-FLASH系列语音芯片凭借其卓越的性能与灵活的支持平台&#xff0c;正逐步引领着…

SpringBoot教程(三十二) | SpringBoot集成Skywalking链路跟踪

SpringBoot教程&#xff08;三十二&#xff09; | SpringBoot集成Skywalking链路跟踪 一、Skywalking是什么&#xff1f;二、Skywalking与JDK版本的对应关系三、Skywalking下载四、Skywalking 数据存储五、Skywalking 的启动六、部署探针前提&#xff1a; Agents 8.9.0 放入 项…

新手小白,如何研究货币相关性

研究货币对之间的相关性可以帮助交易者理解市场动态&#xff0c;从而优化交易策略。以下是一个详细的研究方向&#xff0c;包括每个步骤的代码&#xff0c;以及一些深入探索的建议。 研究方向 选择货币对&#xff1a;确定需要研究的两个货币对。 数据收集&#xff1a;获取选…

掌握免费API:高效获取与智能调用技巧

在数字化时代&#xff0c;免费 API 的应用越来越广泛。它们为开发者提供了丰富的资源和工具&#xff0c;帮助实现多种功能和服务。从数据获取到功能扩展&#xff0c;免费 API 极大地推动了创新和效率的提升。 本文将深入探讨“免费 API 深度求索之路”&#xff0c;涵盖从获取 …

ONLYOFFICE文档8.2:开启无缝PDF协作

ONLYOFFICE 开源办公套件的最新版本新增约30个新功能&#xff0c;并修复了超过500处故障。 什么是 ONLYOFFICE 文档 ONLYOFFICE 文档是一套功能强大的文档编辑器&#xff0c;支持编辑处理文档、表格、幻灯片、可填写的表单和PDF。可多人在线协作&#xff0c;支持插件和 AI 集…

HTTP vs WebSocket

本文将对比介绍HTTP 和 WebSocket &#xff01; 相关文章&#xff1a; 1.HTTP 详解 2.WebSocket 详解 一、HTTP&#xff1a;请求/响应的主流协议 HTTP&#xff08;超文本传输协议&#xff09;是用于发送和接收网页数据的标准协议。它最早于1991年由Tim Berners-Lee提出来&…

建模与辨识【1-3章】

&#xff08;第一章&#xff09;&#xff1a; 建立数学模型的方法&#xff1a; 系统模型的分类&#xff1a;按照不同标准分类有所不同&#xff1a; 误差准则&#xff1a; &#xff08;第二章&#xff09;&#xff1a; 最优输入信号的判断标准: Fisher信息矩阵逆 M序列必考&am…

Redis 性能优化选择:Pika 的配置与使用详解

引言 在我们日常开发中 redis是我们开发业务场景中不可缺少的部分。Redis 凭借其内存存储和快速响应的特点&#xff0c;广泛应用于缓存、消息队列等各种业务场景。然而&#xff0c;随着数据量的不断增长&#xff0c;单节点的 Redis 因为内存限制和并发能力的局限&#xff0c;逐…

数据库->库的操作

目录 一、查看数据库 1.显示所有的数据库 二、创建数据库 1.创建数据库 2.查看警告信息 3.创建一个名为database的数据库 三、字符集编码和校验(排序)规则 1.查看数据库⽀持的字符集编码 2.查看数据库⽀持的排序规则 3.一条完整创建库的语句 4. 不同的字串集与排序规…

大数据新视界 --大数据大厂之 Apache Beam:统一批流处理的大数据新贵

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

5.4章节python中集合创建、删除、增删改

1.集合的创建和删除 2.集合的操作符 3.集合的操作方法和遍历 4.列表、元组、字典、集合的区别 一、集合的创建和删除 集合&#xff08;set&#xff09;是一种内置的数据结构&#xff0c;用于存储唯一且无序的元素。集合是一个可变的数据类型&#xff0c;这意味着你可以添加、删…

【命令操作】Linux上通过mdadm配置软RAID _ 统信 _ 麒麟 _ 方德

原文链接&#xff1a;【命令操作】Linux上通过mdadm配置软RAID | 统信 | 麒麟 | 方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于如何在Linux系统上使用mdadm工具配置软件RAID&#xff08;Redundant Array of Independent Disks&#xff0c;独立磁盘冗余阵列…

2012年国赛高教杯数学建模D题机器人避障问题解题全过程文档及程序

2012年国赛高教杯数学建模 D题 机器人避障问题 图1是一个800800的平面场景图&#xff0c;在原点O(0, 0)点处有一个机器人&#xff0c;它只能在该平面场景范围内活动。图中有12个不同形状的区域是机器人不能与之发生碰撞的障碍物&#xff0c;障碍物的数学描述如下表&#xff1a…