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

2025了,你知道electron-vite吗?

electron-vite工程搭建

使用electron+vite:https://cn.electron-vite.org/

electron-vite 需要 Node.js 版本 20.19+, 22.12+ 和 Vite 版本 5.0+

搭建第一个 electron-vite 项目

npm create @quick-start/electron@latest

✔ Project name: …
✔ Select a framework: › vue
✔ Add TypeScript? … No / Yes
✔ Add Electron updater plugin? … No / Yes
✔ Enable Electron download mirror proxy? … No / Yes

electron-vite 可以智能地为 Electron 的独特环境打包源代码。

主进程和预加载脚本: 无论是在开发还是生产中,这些都会被打包成 CommonJS 模块,并在 Node.js 环境中运行。

渲染器: 在开发过程中,electron-vite 会将 CommonJS / UMD 模块转换为 ES 模块以支持 HMR。在生产过程中,这些将被打包成 IIFE 模块,并在浏览器环境中运行。

项目结构

.
├──src
│  ├──main     # 主进程
│  │  ├──index.ts 
│  │  └──...
│  ├──out  #构建输出
│  │  ├──main
│  │  └──preload
│  │  └──renderer
│  ├──preload     #预加载脚本
│  │  ├──index.ts 
│  │  └──...
│  └──renderer    # with vue, react, etc.
│     ├──src
│     ├──index.html   #渲染器
│     └──...
├──electron.vite.config.ts
├──package.json
└──...

主进程

是应用的核心,负责管理窗口、系统原生 API 调用和进程间通信(IPC)
需要写在主进程的内容:

  1. 窗口管理(BrowserWindow)
    创建、控制应用窗口(大小、位置、菜单等)。
    加载渲染进程(Vue/React 页面)。
// main.ts
import { app, BrowserWindow } from 'electron';
import path from 'path';function createWindow() {const win = new BrowserWindow({width: 1200,webPreferences: {preload: path.join(__dirname, '../preload/index.js'), // 预加载脚本},});// 开发环境加载 Vite 开发服务器,生产环境加载本地文件if (process.env.VITE_DEV_SERVER_URL) {win.loadURL(process.env.VITE_DEV_SERVER_URL);} else {win.loadFile(path.join(__dirname, '../renderer/index.html'));}
}app.whenReady().then(createWindow);
  1. 系统原生 API 调用
    访问文件系统(fs)、系统对话框(dialog)、系统托盘(Tray)等。
import { dialog } from 'electron';// 示例:打开文件选择对话框
ipcMain.handle('open-file-dialog', async () => {const result = await dialog.showOpenDialog({properties: ['openFile'],});return result.filePaths[0];
});
  1. 进程间通信(IPC
    通过 ipcMain 接收渲染进程的请求,执行敏感操作。
// 例如
import { ipcMain } from 'electron';
import fs from 'fs';// 暴露读取文件的方法给渲染进程
ipcMain.handle('read-file', (event, filePath) => {return fs.promises.readFile(filePath, 'utf-8');
});
  1. 应用生命周期管理
    处理应用启动、退出、多窗口管理等。
app.on('window-all-closed', () => {if (process.platform !== 'darwin') app.quit();
});

渲染进程

渲染进程(Renderer Process) 是负责展示用户界面(UI)和运行前端代码(如 HTML、CSS、JavaScript 或 Vue/React 框架)的独立进程。每个 Electron 窗口(BrowserWindow)都对应一个独立的渲染进程,其行为类似于浏览器中的标签页,但具备更强的集成能力(通过配置可与 Node.js 交互)

渲染进程的核心特点:

  1. 基于 Chromium 引擎:每个渲染进程运行在独立的 Chromium 渲染环境中,支持现代前端技术(Vue/React/Angular、WebGL 等)。
  2. 默认隔离性:除非显式配置,否则渲染进程无法直接访问 Node.js 或系统资源(需通过主进程代理)。
  3. 多实例:每个 BrowserWindow 或 标签会创建独立的渲染进程。
    在这里插入图片描述

主进程 vs 渲染进程

在这里插入图片描述

预加载脚本

预加载脚本会在渲染器的网页加载之前注入。如果你想向渲染器加入需要特殊权限的功能,你可以通过 contextBridge 接口定义 全局对象。

预加载脚本的作用:

增强渲染器:预加载脚本运行在具有 HTML DOM APIs 和 Node.js、Electron APIs 的有限子集访问权限的环境中。
在主进程和渲染进程之间通信:使用 Electron 的 ipcMain 和 ipcRenderer
模块进行进程间通信(IPC)。

例如:

  1. 创建一个预加载脚本并通过 contextBridge.exposeInMainWorld 将 方法 或 变量 暴露给渲染器。
import { contextBridge, ipcRenderer } from 'electron'contextBridge.exposeInMainWorld('electron', {ping: () => ipcRenderer.invoke('ping')
})
  1. 将脚本附在渲染进程上,在 BrowserWindow 构造器中使用 webPreferences.preload 传入脚本的路径
import { app, BrowserWindow } from 'electron'
import path from 'path'const createWindow = () => {const win = new BrowserWindow({webPreferences: {preload: path.join(__dirname, 'preload.js'),},})ipcMain.handle('ping', () => 'pong')win.loadFile('index.html')
}app.whenReady().then(() => {createWindow()
})
  1. 在渲染器进程中使用暴露的函数和变量:
const func = async () => {const response = await window.electron.ping()console.log(response) // prints out 'pong'
}func()

沙盒

开启沙盒

特点:
渲染进程运行在严格隔离的环境,类似 Chrome 浏览器标签页:

  1. 无法直接访问 Node.js API(如 fs、path、child_process)。
  2. 无法使用 require 加载模块(除非通过预加载脚本注入)。
  3. 无法操作本地文件系统或执行系统命令。

安全机制

  1. 进程隔离:渲染进程与主进程完全隔离,依赖 IPC 通信。
  2. 上下文隔离(Context Isolation):默认启用,防止全局对象(如 window) 被篡改。
  3. 预加载脚本是唯一桥梁:通过 contextBridge.exposeInMainWorld 安全暴露有限 API。
关闭沙盒

特点:

渲染进程拥有完整 Node.js 访问权限:

  1. 可直接使用 require 加载模块(如 fs)。
  2. 能执行任意系统级操作(如读写文件、启动子进程)。
  3. 需要配合 nodeIntegration: true 和 contextIsolation: false 完全解锁能力。

风险

  1. 高危安全漏洞:如果 Vue 页面存在 XSS 漏洞,攻击者可注入代码删除文件、安装木马等。
  2. 恶意代码能绕过所有浏览器安全限制。
new BrowserWindow({webPreferences: {sandbox: false, // 关闭沙盒nodeIntegration: true, // 启用 Node.js 集成contextIsolation: false // 禁用上下文隔离(允许直接修改全局对象)}
});

在这里插入图片描述
Electron 官方推荐始终开启沙盒,除非有极端性能需求或明确可控的安全边界。

调试

可通过win.webContents.openDevTools({ mode: 'detach' }); ctrl+shift+i打开调试控制台(像浏览器的控制台一样)

package.json命令解读

  "scripts": {"start": "electron-vite preview", //启动开发服务器,支持热更新(HMR)"dev": "electron-vite dev", //在生产环境模式下预览应用(用于测试打包前的效果)"build": "npm run typecheck && electron-vite build", //执行类型检查后,使用 electron-vite 构建生产版本"postinstall": "electron-builder install-app-deps", //安装应用依赖(特别是原生模块)"build:unpack": "npm run build && electron-builder --dir", //electron-builder --dir 输出可执行文件依赖的原始文件结构"build:win": "npm run build && electron-builder --win",  // 打包 Windows 安装包"build:mac": "npm run build && electron-builder --mac", //打包 macOS 应用"build:linux": "npm run build && electron-builder --linux" //打包 Linux 应用},

打包

打包时会自动下载对应版本的 Electron 二进制文件
如下:
在这里插入图片描述

为什么需要下载?
Electron 应用本质上是将你的代码与预编译的 Chromium 和 Node.js 运行时打包在一起。
打包工具(如 electron-builder 或 electron-packager)需要下载对应平台(如 Windows 64 位)和版本(如 v37.2.3)的 Electron 二进制文件作为基础。

这个文件的作用

下载的 ZIP 文件包含:

  1. Chromium 浏览器引擎(用于渲染 HTML/CSS/JS)
  2. Node.js 运行时(用于系统级 API 访问)
  3. Electron 框架本身(主进程 / 渲染进程通信等)

怎么解决下载太慢的问题
可以手动下载,并放到系统的缓存中,再次重新打包。
可将zip文件放置到C:\Users\Administrator\AppDatal\Locall\electron\Cache目录下。如果找不到AppData文件夹,需在文件资源管理器中设置显示隐藏文件。

在这里插入图片描述
打包报错解决

解决了上面electron…zip的问题后,第一次打包可能还会遇到winCodeSign报错的,如下:
在这里插入图片描述
解决方式:

  1. 使用PowerShell 进行打包命令执行,如果不行试试下一个方法
  2. 同样的查看是否在C:\Users\Administrator\AppDatal\Locall\electron\Cache 目录下有提示的winCodeSign的压缩包,如果没有,手动下载放置,同时将winCodeSign解压(保留原来压缩包的名字) 放置到C:\Users\用户名\AppData\Local\electron-builder\Cache\winCodeSign在这里插入图片描述
    再进行打包应该就可以了
    等待进程结束

在这里插入图片描述

打包后的包

默认放置在dist目录下
在这里插入图片描述
外层安装包,双击自动安装并打开
在这里插入图片描述
免安装包:双击打开,外发需要整个文件夹的资源,否则不能打开。
在这里插入图片描述

http://www.xdnf.cn/news/19625.html

相关文章:

  • 网络原理——HTTP/HTTPS
  • ImageMagick命令行图片工具:批量实现格式转换与压缩,支持水印添加及GIF动态图合成
  • 2条命令,5秒安装,1秒启动!Vite项目保姆级上手指南
  • 鸿蒙NEXT界面交互全解析:弹出框、菜单、气泡提示与模态页面的实战指南
  • 开源的聚合支付系统源码/易支付系统 /三方支付系统
  • Erlang 利用 recon 排查热点进程
  • 人工智能之数学基础:分布函数对随机变量的概率分布情况进行刻画
  • 微信小程序 navigateTo 栈超过多层后会失效
  • 在 Delphi 5 中获取 Word 文档页数的方法
  • 小程序蓝牙低功耗(BLE)外围设备开发指南
  • 365 天技术创作手记:从一行代码到四万同行者的相遇
  • C++多线程编程:std::thread, std::async, std::future
  • Jenkins Pipeline 语法
  • 第 12 篇:网格边界安全 - Egress Gateway 与最佳实践
  • python中的zip() 函数介绍及使用说明
  • 基于Spark的新冠肺炎疫情实时监控系统_django+spider
  • HTML第三课:特殊元素
  • 跨境电商账号风控核心:IP纯净度与浏览器指纹的防护策略
  • 跳出“中央集权”的泥潭:以Data Mesh重构AI时代的活性数据治理
  • MySQL8.0 新特性随笔
  • css中 ,有哪些⽅式可以隐藏页⾯元素? 区别?
  • 详细介绍RIGHT JOIN及其用法
  • Vue2 入门(一)介绍及Demo项目创建
  • 【51单片机6位数码管显示矩阵键值至右向左自左向右】2022-11-29
  • Linux驱动开发学习笔记
  • web自动化测试(selenium)
  • [架构之美]pdf压缩实战笔记(十五)
  • FlutterUnit 3.3.0 | 全组件、全属性、鸿蒙支持来袭
  • 高德开放平台智能眼镜解决方案,Rokid Glasses AR导航实测
  • Proxy 我踩过的那些坑