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的警官

      • <meta
          http-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 -->
        <meta
          http-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 -->
          <meta
            http-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)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

不使用扩展,win10下网页长截图

安卓手机&#xff0c;各大厂商都会有自带的长截图工具&#xff0c; 用起来很方便&#xff0c; 反而是windows桌面版网页长截图&#xff0c; 偶尔会用下&#xff0c;用得不多&#xff0c; 用一次后下次用又忘记了&#xff0c; 今天正好要用到&#xff0c; 特记录下方便以后查阅…

TCP simultaneous open测试

源代码 /*************************************************************************> File Name: common.h> Author: hsz> Brief:> Created Time: 2024年10月23日 星期三 09时47分51秒**********************************************************************…

深度学习技术演进:从 CNN、RNN 到 Transformer 的发展与原理解析

深度学习的技术演进经历了从卷积神经网络&#xff08;CNN&#xff09;到循环神经网络&#xff08;RNN&#xff09;再到 Transformer 的重要发展。这三个架构分别擅长处理图像、序列数据和多种任务的特征&#xff0c;标志着深度学习在不同领域取得的进步。 1. 卷积神经网络&…

旧电脑安装Win11提示“这台电脑当前不满足windows11系统要求”,安装中断。怎么办?

前言 最近有很多小伙伴也获取了LTSC版本的Win11镜像&#xff0c;很大一部分小伙伴安装这个系统也是比较顺利的。 有顺利安装完成的&#xff0c;肯定也有安装不顺利的。这都是很正常的事情&#xff0c;毕竟这个镜像对电脑硬件要求还是挺高的。 有一部分小伙伴在安装Windows11 …

Flutter项目打包ios, Xcode 发布报错 Module‘flutter barcode_scanner‘not found

报错图片 背景 flutter 开发的 apple app 需要发布新版本&#xff0c;但是最后一哆嗦碰到个报错&#xff0c;这个小问题卡住了我一天&#xff0c;之间的埪就不说了&#xff0c;直接说我是怎么解决的&#xff0c;满满干货 思路 这个报错 涉及到 flutter_barcode_scanner; 所…

基于Python+SQL Server2008实现(GUI)快递管理系统

快递业务管理系统的设计与实现 摘要: 着网络新零售的到来&#xff0c;传统物流在网购的洗礼下迅速蜕变&#xff0c;在这场以互联网为基础的时代变革中&#xff0c;哪家企业能率先转变其工作模式就能最先分得一杯羹&#xff0c;物流管理也不例外。传统的物流管理模式效率低下&a…

聚焦IOC容器刷新环节postProcessBeanFactory(BeanFactory后置处理)专项

目录 一、IOC容器的刷新环节快速回顾 二、postProcessBeanFactory源码展示分析 &#xff08;一&#xff09;模版方法postProcessBeanFactory &#xff08;二&#xff09;AnnotationConfigServletWebServerApplicationContext 调用父类的 postProcessBeanFactory 包扫描 …

62页PPT | 项目企业信息化现状调研与流程改进方案

这份PPT详细介绍了企业在C2M项目中的信息化现状调研与流程改进方案&#xff0c;涵盖了销售、采购、仓库、物流、CAD制图、CAM编程、计划、生产、质检和财务管理等多个部门的现行流程分析、作业瓶颈、未来流程建议以及针对性的改善建议&#xff0c;旨在通过信息化手段提升企业的…

这是一篇vue3 的详细教程

Vue 3 详细教程 一、Vue 3 简介 Vue.js 是一款流行的 JavaScript 前端框架&#xff0c;用于构建用户界面。Vue 3 是其最新版本&#xff0c;带来了许多新特性和性能优化&#xff0c;使开发更加高效和灵活。 二、环境搭建 安装 Node.js 前往Node.js 官方网站下载并安装适合你…

网站的SSL证书快到期了怎么办?怎么续签?

网站的SSL证书即将到期时&#xff0c;需要续签一个新的证书以保持网站的安全性和信任度。以下是续签SSL证书的一般步骤&#xff1a; 1. 选择证书提供商 如果您之前使用的是免费证书&#xff0c;您可以选择继续使用同一提供商的免费证书服务进行续签。如果您需要更高级别的证书…

Python:背景知识及环境安装

一、计算机的基础概念 1.1 什么是计算机&#xff1f; 最早我们有计算器&#xff0c;但是他只能完成算数运算的功能 而计算机能完成的工作有&#xff1a; &#xff08;1&#xff09;算术运算 &#xff08;2&#xff09;逻辑判断 &#xff08;3&#xff09;数据存储 &#xff08…

【AI学习】Mamba学习(十二):深入理解S4模型

#1024程序员节&#xff5c;征文# HiPPO的学习暂告一段落&#xff0c;按照“HiPPO->S4->Mamba 演化历程”&#xff0c;接着学习S4。 S4对应的论文&#xff1a;《Efficiently Modeling Long Sequences with Structured State Spaces》 文章链接&#xff1a;https://ar5iv…

Two output files share the same path but have different contents

报错 ✘ [ERROR] Two output files share the same path but have different contents: node_modules/.vite/deps_temp_c5811052/three_examples_jsm_controls_orbitControls__js.js7:48:33 PM [vite] error while updating dependencies: Error: Build failed with 1 error: …

7款视频转换器大测评!哪款是最适合你的视频格式转换器?

视频已成为我们生活中不可或缺的一部分&#xff0c;但不同的设备、平台和软件往往支持不同的视频格式&#xff0c;这给我们的视频分享、编辑和播放带来了不少困扰。因此&#xff0c;一款高效、易用的视频格式转换器成为了许多人的必备工具。本文将从软件界面、功能特性、难易程…

利用移动式三维扫描技术创建考古文物的彩色纹理网格【上海沪敖3D】

文章来源于蔡司工业质量解决方案&#xff0c;作者蔡司工业质量 在考古环境中&#xff0c;三维扫描技术应用广泛&#xff0c;如存档、保存、复制和分享&#xff08;包括实体和虚拟形式&#xff09;。 文中&#xff0c;通过真实的扫描案例&#xff0c;您将了解到三维光学解决方案…

实战-任意文件下载

实战-任意文件下载 1、开局 开局一个弱口令&#xff0c;正常来讲我们一般是弱口令或者sql&#xff0c;或者未授权 那么这次运气比较好&#xff0c;直接弱口令进去了 直接访问看看有没有功能点&#xff0c;正常做测试我们一定要先找功能点 发现一个文件上传点&#xff0c;不…

022_matrix_dancing_in_Matlab中求解一个超简单的矩阵问题

矩阵体操 首先&#xff0c;可以复习一下向量、矩阵和索引的基础知识。 向量约定矩阵约定矩阵索引 一般而言&#xff0c;我们利用进行计算大概就是以下的步骤&#xff1a; #mermaid-svg-UovF0Uldf5XxntJi {font-family:"trebuchet ms",verdana,arial,sans-serif;fo…

Webserver(2)GCC

目录 安装GCCVScode远程连接到虚拟机编写代码gcc编译过程gcc与g的区别Xftp连接虚拟机上传文件 安装GCC sudo apt install gcc g查看版本是7.5 touch test.c创建代码 但是在虚拟机中写代码很不方便 VScode远程连接到虚拟机编写代码 gcc test.c -o app在虚拟机中用gcc编译的…

世界肺癌日:新药涌现:不断拓展治疗边界

肺癌&#xff0c;这一全球性的健康杀手&#xff0c;每分钟都无情地夺去超过三人的生命&#xff0c;每年导致约180万人不幸离世&#xff0c;占据了全球癌症死亡人数的18%&#xff0c;成为癌症死亡的首要原因。患者不仅要承受生理上的巨大痛苦&#xff0c;还要面对心理上的沉重压…

OpenCV高级图形用户界面(20)更改窗口的标题函数setWindowTitle()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在OpenCV中&#xff0c;cv::setWindowTitle函数用于更改窗口的标题。这使得您可以在程序运行时动态地更改窗口的标题文本。 函数原型 void cv::…