Electron + React + Vite 实践

目录

前言

项目结构:

cpp 复制代码
my-app/
├─ electron/
│  ├─ main.ts
│  └─ preload.ts
├─ src/
│  ├─ App.jsx
│  └─ main.jsx
├─ package.json
└─ vite.config.ts

【注意】:
不要使用 CRA(Create React App)构建 Electron 项目,Vite 支持 ESM 和快速 HMR,更适合现代 Electron 开发

一、Electron 主流程集成

1、主进程 main.ts

cpp 复制代码
import { app, BrowserWindow } from 'electron';
import path from 'path';

let mainWindow: BrowserWindow;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false
    }
  });

  if (process.env.NODE_ENV === 'development') {
    mainWindow.loadURL('http://localhost:5173'); // Vite Dev Server
  } else {
    mainWindow.loadFile(path.join(__dirname, '../dist/index.html'));
  }
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

2、Preload 脚本 preload.ts

cpp 复制代码
import { contextBridge, ipcRenderer } from 'electron';

contextBridge.exposeInMainWorld('electronAPI', {
  sendMessage: (msg: string) => ipcRenderer.send('message', msg),
  onMessage: (callback: (event: any, data: any) => void) => ipcRenderer.on('message-reply', callback)
});

关键点:

  • 使用 contextBridge 替代 nodeIntegration = true。
  • Renderer 只能通过安全 API 调用 Node 功能。

二、React 调用 Electron

采用 React 18 + Hooks:

cpp 复制代码
import { useEffect } from 'react';

function App() {
  const sendMsg = () => window.electronAPI.sendMessage('Hello Electron');

  useEffect(() => {
    window.electronAPI.onMessage((_e, data) => {
      console.log('Received:', data);
    });
  }, []);

  return <button onClick={sendMsg}>Send Message</button>;
}

export default App;

【注意】:

  • window.electronAPI 来自 Preload 安全桥接。
  • 避免直接在 Renderer 中使用 Node API。

三、打包与跨平台

1、使用 electron-builder

在 package.json 添加:

json 复制代码
"build": {
  "appId": "com.example.app",
  "directories": { "output": "release" },
  "files": ["dist/**/*", "electron/**/*"],
  "mac": { "target": "dmg" },
  "win": { "target": "nsis" },
  "linux": { "target": "AppImage" }
}
  • dist:Vite 前端打包产物
  • electron:主进程 & preload
  • 注意 macOS 需要签名 (notarize)

2、打包流程

bash 复制代码
# 前端打包
vite build

# Electron 打包
electron-builder

四、实际开发注意事项

1、开发环境:

  • 使用 concurrently 启动 Vite 和 Electron:
json 复制代码
"dev": "concurrently \"vite\" \"electron .\""

2、Renderer Node 安全:

  • 永远不要在 Renderer 中直接启用 Node。
  • 所有文件操作通过 Preload/IPC。

3、跨平台文件路径:

  • 使用 path.join,避免 Windows/Unix 路径差异。
  • 打包时注意 __dirname 的路径。

4、多窗口 / 多进程优化:

  • 渲染复杂 SPA 页面时,优先复用窗口或 BrowserView。
  • 关闭窗口时记得 win = null 回收。
相关推荐
AAA阿giao4 小时前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架
摘星编程16 小时前
React Native鸿蒙版:Image图片占位符
react native·react.js·harmonyos
飞羽殇情1 天前
基于React Native鸿蒙跨平台开发构建完整电商预售系统数据模型,完成参与预售、支付尾款、商品信息展示等
react native·react.js·华为·harmonyos
摘星编程1 天前
React Native + OpenHarmony:ImageSVG图片渲染
javascript·react native·react.js
摘星编程1 天前
OpenHarmony + RN:Text文本书写模式
javascript·react native·react.js
xixixin_1 天前
【React】中 Body 类限定法:优雅覆盖挂载到 body 的组件样式
前端·javascript·react.js
摘星编程1 天前
用React Native开发OpenHarmony应用:Image网络图片加载
javascript·react native·react.js
摘星编程1 天前
OpenHarmony环境下React Native:ImageBase64图片显示
javascript·react native·react.js
摘星编程1 天前
React Native鸿蒙:Image本地图片显示
javascript·react native·react.js
刘联其1 天前
.net也可以用Electron开发跨平台的桌面程序了
前端·javascript·electron