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

react+umi项目如何添加electron的功能

流程

1、安装Electron相关依赖包
2、创建Electron主进程文件(main.js)
3、修改package.json添加Electron启动脚本
4、测试Electron应用启动和功能
5、创建Electron预加载脚本(preload.js)
6、配置Electron构建和打包脚本
7、添加测试页面

效果

在这里插入图片描述

1、安装Electron相关依赖包

npm install --save-dev electron electron-builder 

安装依赖遇到的相关问题
1)发现遇到冲突

npm install --save-dev electron electron-builder --legacy-peer-deps 

2) 网络连接问题导致Electron下载失败。使用yarn来安装,或者设置淘宝镜像源来解决网络问题。

npm config set registry https://registry.npmmirror.com 

3)设置镜像源成功。现在再次尝试安装Electron相关依赖。发现问题持续存在。设置Electron的镜像源来解决下载问题。

npm config set electron_mirror https://npmmirror.com/mirrors/electron/ 

4)设置镜像源成功。现在再次尝试安装Electron相关依赖。问题依旧存在。使用正确的环境变量来设置Electron镜像源。

$env:ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/" 

5)现在设置了Electron镜像源,再次尝试安装Electron依赖,安装成功
6)更新todo状态并开始创建Electron主进程文件。

  • 6.1) 现在需要安装concurrently和wait-on依赖,这些是electron:dev脚本需要的工具
npm install --save-dev concurrently wait-on --legacy-peer-deps 
  • 6.2)现在添加Electron构建配置到package.json文件中。
  • 6.3)现在测试Electron应用。首先启动开发环境的Electron应用,这会同时启动React开发服务器和Electron窗口。

2、创建Electron主进程文件(main.js)

const { app, BrowserWindow, Menu, ipcMain, dialog, shell, Notification } = require('electron');
const path = require('path');
const isDev = process.env.NODE_ENV === 'development';// 保持对window对象的全局引用,避免JavaScript垃圾回收时窗口被自动关闭
let mainWindow;function createWindow() {// 创建浏览器窗口mainWindow = new BrowserWindow({width: 1200,height: 800,webPreferences: {nodeIntegration: false, // 出于安全考虑,禁用node集成contextIsolation: true, // 启用上下文隔离enableRemoteModule: false, // 禁用remote模块preload: path.join(__dirname, 'preload.js') // 预加载脚本},icon: path.join(__dirname, 'public/icons/favicon.ico'), // 应用图标show: false, // 初始时不显示窗口,等加载完成后再显示titleBarStyle: 'default'});// 加载应用if (isDev) {// 开发环境:先尝试加载开发服务器,如果失败则加载测试页面mainWindow.loadURL('http://localhost:8000').catch(() => {console.log('开发服务器未启动,加载测试页面');mainWindow.loadFile(path.join(__dirname, 'test-electron.html'));});// 打开开发者工具mainWindow.webContents.openDevTools();} else {// 生产环境:加载打包后的文件mainWindow.loadFile(path.join(__dirname, 'dist/index.html'));}// 当页面加载完成后显示窗口mainWindow.once('ready-to-show', () => {mainWindow.show();});// 当窗口被关闭时,取消引用window对象mainWindow.on('closed', () => {mainWindow = null;});// 处理外部链接mainWindow.webContents.setWindowOpenHandler(({ url }) => {require('electron').shell.openExternal(url);return { action: 'deny' };});
}// Electron初始化完成,创建窗口
app.whenReady().then(() => {createWindow();// 在macOS上,当点击dock图标且没有其他窗口打开时,重新创建窗口app.on('activate', () => {if (BrowserWindow.getAllWindows().length === 0) {createWindow();}});
});// 当所有窗口都被关闭时退出应用
app.on('window-all-closed', () => {// 在macOS上,应用和菜单栏会保持活跃状态,直到用户明确退出if (process.platform !== 'darwin') {app.quit();}
});// 在开发环境中启用热重载
if (isDev) {try {require('electron-reload')(__dirname, {electron: path.join(__dirname, 'node_modules', '.bin', 'electron'),hardResetMethod: 'exit'});} catch (err) {console.log('electron-reload not found, hot reload disabled');}
}// 设置应用菜单
const template = [{label: '文件',submenu: [{label: '退出',accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Ctrl+Q',click: () => {app.quit();}}]},{label: '编辑',submenu: [{ label: '撤销', accelerator: 'CmdOrCtrl+Z', role: 'undo' },{ label: '重做', accelerator: 'Shift+CmdOrCtrl+Z', role: 'redo' },{ type: 'separator' },{ label: '剪切', accelerator: 'CmdOrCtrl+X', role: 'cut' },{ label: '复制', accelerator: 'CmdOrCtrl+C', role: 'copy' },{ label: '粘贴', accelerator: 'CmdOrCtrl+V', role: 'paste' }]},{label: '视图',submenu: [{ label: '重新加载', accelerator: 'CmdOrCtrl+R', role: 'reload' },{ label: '强制重新加载', accelerator: 'CmdOrCtrl+Shift+R', role: 'forceReload' },{ label: '开发者工具', accelerator: 'F12', role: 'toggleDevTools' },{ type: 'separator' },{ label: '实际大小', accelerator: 'CmdOrCtrl+0', role: 'resetZoom' },{ label: '放大', accelerator: 'CmdOrCtrl+Plus', role: 'zoomIn' },{ label: '缩小', accelerator: 'CmdOrCtrl+-', role: 'zoomOut' },{ type: 'separator' },{ label: '全屏', accelerator: 'F11', role: 'togglefullscreen' }]},{label: '窗口',submenu: [{ label: '最小化', accelerator: 'CmdOrCtrl+M', role: 'minimize' },{ label: '关闭', accelerator: 'CmdOrCtrl+W', role: 'close' }]}
];const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);// IPC 处理程序
ipcMain.handle('window-minimize', () => {const win = BrowserWindow.getFocusedWindow();if (win) win.minimize();
});ipcMain.handle('window-maximize', () => {const win = BrowserWindow.getFocusedWindow();if (win) {if (win.isMaximized()) {win.unmaximize();} else {win.maximize();}}
});ipcMain.handle('window-close', () => {const win = BrowserWindow.getFocusedWindow();if (win) win.close();
});ipcMain.handle('dialog-open-file', async () => {const result = await dialog.showOpenDialog({properties: ['openFile'],filters: [{ name: 'All Files', extensions: ['*'] },{ name: 'Images', extensions: ['jpg', 'png', 'gif'] },{ name: 'Documents', extensions: ['pdf', 'doc', 'docx'] }]});return result;
});ipcMain.handle('dialog-save-file', async (event, data) => {const result = await dialog.showSaveDialog({filters: [{ name: 'JSON Files', extensions: ['json'] },{ name: 'Text Files', extensions: ['txt'] },{ name: 'All Files', extensions: ['*'] }]});if (!result.canceled && result.filePath) {const fs = require('fs');try {fs.writeFileSync(result.filePath, JSON.stringify(data, null, 2));return { success: true, filePath: result.filePath };} catch (error) {return { success: false, error: error.message };}}return { success: false, canceled: true };
});ipcMain.handle('show-notification', (event, { title, body }) => {if (Notification.isSupported()) {new Notification({ title, body }).show();return { success: true };}return { success: false, error: 'Notifications not supported' };
});ipcMain.handle('get-app-version', () => {return app.getVersion();
});ipcMain.handle('set-theme', (event, theme) => {// 这里可以实现主题切换逻辑console.log('Setting theme to:', theme);return { success: true, theme };
});ipcMain.handle('get-theme', () => {// 返回当前主题return 'light'; // 默认主题
});ipcMain.handle('open-dev-tools', () => {const win = BrowserWindow.getFocusedWindow();if (win) {win.webContents.openDevTools();return { success: true };}return { success: false };
});ipcMain.handle('check-for-updates', () => {// 这里可以实现更新检查逻辑console.log('Checking for updates...');return { hasUpdate: false, version: app.getVersion() };
});ipcMain.handle('log', (event, { level, message }) => {console.log(`[${level.toUpperCase()}] ${message}`);return { success: true };
});

3、修改package.json添加Electron启动脚本

{"main": "main.js","homepage": "./","scripts": {"electron": "cross-env NODE_ENV=development electron .","electron:dev": "concurrently \"npm run start:dev\" \"wait-on http://localhost:8000 && cross-env NODE_ENV=development electron .\"","electron:build": "npm run build && cross-env NODE_ENV=production electron .","electron:pack": "npm run build && electron-builder","electron:dist": "npm run build && electron-builder --publish=never"},"devDependencies":{"concurrently": "^9.2.1","electron": "^38.0.0","electron-builder": "^26.0.12","wait-on": "^8.0.4"}
}

4、测试Electron应用启动和功能

npm run electron:dev 

npm run start:dev #单独启动React开发服务器来确保它能正常工作。
npm run electron # 检查Electron的启动状态

5、创建Electron预加载脚本(preload.js)

const { contextBridge, ipcRenderer } = require('electron');// 通过contextBridge暴露安全的API给渲染进程
contextBridge.exposeInMainWorld('electronAPI', {// 系统信息platform: process.platform,version: process.versions,// 窗口控制minimize: () => ipcRenderer.invoke('window-minimize'),maximize: () => ipcRenderer.invoke('window-maximize'),close: () => ipcRenderer.invoke('window-close'),// 文件操作openFile: () => ipcRenderer.invoke('dialog-open-file'),saveFile: (data) => ipcRenderer.invoke('dialog-save-file', data),// 通知showNotification: (title, body) => ipcRenderer.invoke('show-notification', { title, body }),// 应用信息getAppVersion: () => ipcRenderer.invoke('get-app-version'),// 监听器onMenuAction: (callback) => {ipcRenderer.on('menu-action', callback);// 返回清理函数return () => ipcRenderer.removeListener('menu-action', callback);},// 主题切换setTheme: (theme) => ipcRenderer.invoke('set-theme', theme),getTheme: () => ipcRenderer.invoke('get-theme'),// 开发工具openDevTools: () => ipcRenderer.invoke('open-dev-tools'),// 检查更新checkForUpdates: () => ipcRenderer.invoke('check-for-updates'),// 日志log: {info: (message) => ipcRenderer.invoke('log', { level: 'info', message }),warn: (message) => ipcRenderer.invoke('log', { level: 'warn', message }),error: (message) => ipcRenderer.invoke('log', { level: 'error', message })}
});// 在窗口加载完成后通知主进程
window.addEventListener('DOMContentLoaded', () => {// 可以在这里添加一些初始化逻辑console.log('Preload script loaded');
});// 错误处理
window.addEventListener('error', (event) => {console.error('Renderer process error:', event.error);
});window.addEventListener('unhandledrejection', (event) => {console.error('Unhandled promise rejection:', event.reason);
});

6、配置Electron构建和打包脚本

{"main": "main.js","homepage": "./","build": {"appId": "com.yunchuang.hdbsmk50","productName": "HdbsMk50","directories": {"output": "electron-dist"},"files": ["dist/**/*","main.js","preload.js","node_modules/**/*","public/icons/**/*"],"mac": {"category": "public.app-category.productivity","target": [{"target": "dmg","arch": ["x64", "arm64"]}]},"win": {"target": [{"target": "nsis","arch": ["x64"]}]},"linux": {"target": [{"target": "AppImage","arch": ["x64"]}]},"nsis": {"oneClick": false,"allowToChangeInstallationDirectory": true}}
}

7、添加测试页面

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Electron Test</title><style>body {font-family: Arial, sans-serif;margin: 0;padding: 20px;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);color: white;text-align: center;}.container {max-width: 600px;margin: 0 auto;padding: 40px;background: rgba(255, 255, 255, 0.1);border-radius: 10px;backdrop-filter: blur(10px);}h1 {font-size: 2.5em;margin-bottom: 20px;}.info {background: rgba(255, 255, 255, 0.2);padding: 20px;border-radius: 8px;margin: 20px 0;}button {background: #4CAF50;color: white;border: none;padding: 12px 24px;font-size: 16px;border-radius: 5px;cursor: pointer;margin: 10px;}button:hover {background: #45a049;}</style>
</head>
<body><div class="container"><h1>🚀 Electron 测试页面</h1><p>恭喜!Electron 应用已成功启动!</p><div class="info"><h3>系统信息</h3><p id="platform">平台: 加载中...</p><p id="version">版本: 加载中...</p></div><div class="info"><h3>功能测试</h3><button onclick="testNotification()">测试通知</button><button onclick="testDevTools()">打开开发者工具</button><button onclick="testLog()">测试日志</button></div><div class="info"><h3>状态</h3><p id="status">✅ Electron 集成成功!</p></div></div><script>// 检查是否在Electron环境中if (window.electronAPI) {document.getElementById('platform').textContent = `平台: ${window.electronAPI.platform}`;document.getElementById('version').textContent = `Node版本: ${window.electronAPI.version.node}`;function testNotification() {window.electronAPI.showNotification('测试通知', '这是一个来自Electron的测试通知!');}function testDevTools() {window.electronAPI.openDevTools();}function testLog() {window.electronAPI.log.info('这是一条测试日志信息');alert('日志已发送到控制台');}} else {document.getElementById('platform').textContent = '平台: 浏览器环境';document.getElementById('version').textContent = '版本: 非Electron环境';document.getElementById('status').textContent = '⚠️ 当前在浏览器中运行,不是Electron环境';function testNotification() {alert('通知功能仅在Electron环境中可用');}function testDevTools() {alert('开发者工具功能仅在Electron环境中可用');}function testLog() {console.log('这是一条测试日志信息');alert('日志已发送到浏览器控制台');}}</script>
</body>
</html>
http://www.xdnf.cn/news/1464895.html

相关文章:

  • PyTorch 中.backward() 详解使用
  • 前后端国密加密传输用户密码流程
  • Unity 解决天空盒中间出现一条线
  • flink 伪代码
  • 高效管理网络段和端口集合的工具之ipset
  • Bug排查日记:高效记录与解决之道
  • 高通AR1平台Recovery架构分析与自动恢复出厂设置实现
  • 从 elecworks 到云端协同:SOLIDWORKS Electrical 发展历史 + 核心功能 + 采购指南
  • Linux 磁盘扩容及分区相关操作实践
  • 从Java全栈到云原生:一场技术深度对话
  • Golang语言设计理念
  • 【GEOS-Chem伴随模型第一期】GEOS-Chem Adjoint 模型详解
  • 常见Bash脚本漏洞分析与防御
  • 【Flutter】RefreshIndicator 无法下拉刷新问题
  • 【存储选型终极指南】RustFS vs MinIO:5大维度深度对决,95%技术团队的选择秘密!
  • LeetCode 131 分割回文串
  • 【LeetCode热题100道笔记】删除链表的倒数第 N 个结点
  • Kafka核心原理与常见面试问题解析
  • 《AI 问答系统:从开发到落地,关键技术与实践案例全解析》
  • 【技术教程】如何将文档编辑器集成至基于Java的Web应用程序
  • c++工程如何提供http服务接口
  • 基于 GEE 批量下载 Landsat8 地表温度(LST)数据
  • 【计算机科学与应用】砚文化虚拟博物馆的Unity3D设计
  • 理解损失函数:机器学习的指南针与裁判
  • 踩坑实录:Django继承AbstractUser时遇到的related_name冲突及解决方案
  • 【Flask】测试平台中,记一次在vue2中集成编辑器组件tinymce
  • XR数字融合工作站打造智能制造专业学习新范式
  • windows通过xrdp远程连接Ubuntu黑屏问题解决
  • FDTD_3 d mie_仿真
  • 计算机毕设选题:基于Python数据挖掘的高考志愿推荐系统