Electron开发的核心功能要点总结,旨在帮助快速掌握Electron开发核心逻辑

文章目录

Electron开发的核心功能要点总结

一、项目创建

核心要点:
  • Electron基于Node.js,需通过npm管理依赖
  • 推荐使用脚手架简化创建流程(如electron-forgeelectron-vite
实例(手动创建):
bash 复制代码
# 1. 初始化项目
mkdir electron-demo && cd electron-demo
npm init -y

# 2. 安装Electron(开发依赖)
npm install electron --save-dev

# 3. 配置package.json(关键字段)
{
  "name": "electron-demo",
  "version": "1.0.0",
  "main": "main.js",  // 主进程入口文件
  "scripts": {
    "start": "electron ."  // 启动命令
  }
}
注意事项:
  • 确保Node.js版本≥14(Electron对Node版本有最低要求)
  • 国内环境建议配置npm镜像(如npm config set electron_mirror https://npmmirror.com/mirrors/electron/

二、配置文件设置

核心要点:
  • 主配置文件:package.json(指定主进程入口、脚本命令等)
  • 主进程窗口配置:通过BrowserWindow参数定义窗口属性
实例(主进程窗口配置):
javascript 复制代码
// main.js(主进程)
const { app, BrowserWindow } = require('electron')

function createWindow() {
  // 创建浏览器窗口
  const mainWindow = new BrowserWindow({
    width: 800,  // 窗口宽度
    height: 600, // 窗口高度
    title: "Electron示例", // 窗口标题
    webPreferences: {
      nodeIntegration: false, // 禁用Node.js集成(安全建议)
      contextIsolation: true, // 启用上下文隔离(默认开启,安全隔离)
      preload: path.join(__dirname, 'preload.js') // 预加载脚本(进程通信桥梁)
    }
  })

  // 加载渲染进程页面
  mainWindow.loadFile('index.html')

  // 打开开发者工具
  mainWindow.webContents.openDevTools()
}
注意事项:
  • nodeIntegration: true存在安全风险(允许渲染进程直接访问Node API),建议禁用
  • preload.js是安全暴露API给渲染进程的唯一推荐方式

三、主进程与渲染进程

核心概念:
  • 主进程

    • 运行在Node.js环境,一个应用只有一个主进程
    • 负责管理窗口、菜单、系统资源(如文件、网络)等
    • 入口:package.jsonmain字段指定的文件(如main.js
  • 渲染进程

    • 每个窗口对应一个渲染进程,运行在Chromium环境
    • 负责页面渲染(HTML/CSS/JS),可使用前端框架(Vue/React等)
    • 入口:通过mainWindow.loadFile('index.html')加载的HTML文件
实例(渲染进程页面):
html 复制代码
<!-- index.html(渲染进程) -->
<!DOCTYPE html>
<html>
  <body>
    <h1>Hello Electron!</h1>
    <button id="sendBtn">发送消息给主进程</button>
    <script src="renderer.js"></script> <!-- 渲染进程脚本 -->
  </body>
</html>
注意事项:
  • 主进程不能直接操作DOM,DOM操作必须在渲染进程中完成
  • 渲染进程默认无法访问Node API,需通过preload.js安全暴露

四、主进程与渲染进程交互

核心方式:
  • IPC(Inter-Process Communication) :通过ipcMain(主进程)和ipcRenderer(渲染进程)实现
实例1:渲染进程发送消息→主进程接收并回复
javascript 复制代码
// 1. 主进程(main.js)
const { ipcMain } = require('electron')

// 监听渲染进程消息
ipcMain.handle('renderer-msg', async (event, arg) => {
  console.log('主进程收到:', arg) // 输出:"Hello 主进程"
  return '主进程已收到消息' // 回复渲染进程
})
javascript 复制代码
// 2. 预加载脚本(preload.js):暴露IPC API给渲染进程
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
  sendMsg: (msg) => ipcRenderer.invoke('renderer-msg', msg)
})
javascript 复制代码
// 3. 渲染进程(renderer.js)
document.getElementById('sendBtn').addEventListener('click', async () => {
  const response = await window.electronAPI.sendMsg('Hello 主进程')
  console.log('渲染进程收到回复:', response) // 输出:"主进程已收到消息"
})
实例2:主进程主动发送消息→渲染进程
javascript 复制代码
// 1. 主进程(main.js):向渲染进程发送消息
mainWindow.webContents.send('main-msg', '来自主进程的通知')
javascript 复制代码
// 2. 预加载脚本(preload.js):暴露监听方法
contextBridge.exposeInMainWorld('electronAPI', {
  onMainMsg: (callback) => ipcRenderer.on('main-msg', (event, arg) => callback(arg))
})
javascript 复制代码
// 3. 渲染进程(renderer.js):监听主进程消息
window.electronAPI.onMainMsg((msg) => {
  console.log('渲染进程收到主进程消息:', msg) // 输出:"来自主进程的通知"
})
注意事项:
  • 禁止在渲染进程中处理敏感操作(如文件写入、系统命令),应交给主进程处理
  • 使用contextBridge暴露API时,避免直接暴露ipcRenderer(防止滥用)
  • 消息命名建议使用业务前缀(如file:savewindow:minimize),避免冲突

五、组件交互(渲染进程内部)

核心要点:
  • 渲染进程内的组件交互与普通前端项目一致,依赖前端框架的状态管理机制
实例(Vue组件交互):
vue 复制代码
<!-- 父组件 -->
<template>
  <ChildComponent @child-event="handleChildEvent" />
</template>
<script>
export default {
  methods: {
    handleChildEvent(data) {
      console.log('父组件收到子组件数据:', data)
    }
  }
}
</script>

<!-- 子组件 -->
<template>
  <button @click="sendToParent">发送数据给父组件</button>
</template>
<script>
export default {
  methods: {
    sendToParent() {
      this.$emit('child-event', '来自子组件的数据')
    }
  }
}
</script>
注意事项:
  • 渲染进程内的组件通信与Electron无关,遵循前端框架自身规范
  • 若需跨窗口(不同渲染进程)通信,需通过主进程转发(主进程作为中介)

六、进程挂载(应用初始化)

核心要点:
  • 主进程挂载:应用启动时初始化窗口、配置、监听事件
  • 渲染进程挂载:页面加载时初始化DOM、绑定事件、调用API
实例(主进程初始化流程):
javascript 复制代码
// main.js
const { app, BrowserWindow } = require('electron')
const path = require('path')

// 应用就绪后创建窗口
app.whenReady().then(() => {
  createWindow() // 创建主窗口

  // 监听应用激活事件(macOS特有)
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// 所有窗口关闭时退出应用(Windows/Linux)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit()
})
注意事项:
  • 窗口创建必须在app.whenReady()回调中执行(确保应用初始化完成)
  • macOS应用关闭所有窗口后不会退出,需监听activate事件重新创建窗口

七、其他关键注意事项

  1. 安全配置

    • 启用contextIsolation: true(默认开启),隔离主进程与渲染进程上下文

    • 设置Content-Security-Policy(CSP)防止XSS攻击:

      html 复制代码
      <meta http-equiv="Content-Security-Policy" content="default-src 'self'">
  2. 调试技巧

    • 主进程调试:npm start --inspect=5858,通过chrome://inspect连接
    • 渲染进程调试:mainWindow.webContents.openDevTools()打开开发者工具
  3. 打包发布

    • 使用electron-builderelectron-packager,配置package.jsonbuild字段指定图标、平台等
    • 示例:npm install electron-builder --save-dev,添加脚本"package": "electron-builder"

通过以上要点,可快速掌握Electron的核心开发流程,重点关注主进程与渲染进程的职责划分及安全通信方式。

在Electron开发中,渲染进程获取环境变量、主进程的角色定位是核心问题,涉及安全隔离与进程职责划分。下面详细说明并举例:

Electron api-主进程、渲染进程及通信补充

一、主进程的核心作用(附实例)

主进程是Electron应用的"大脑",运行在Node.js环境中,负责管理应用生命周期、系统资源交互、窗口创建等核心功能。一个应用只有一个主进程,其核心作用如下:

1. 管理应用生命周期

控制应用的启动、退出、激活等状态,响应系统级事件(如窗口关闭、应用激活)。

实例

javascript 复制代码
// main.js(主进程)
const { app } = require('electron');

// 应用初始化完成后触发(必须在此时创建窗口)
app.whenReady().then(() => {
  console.log('应用已就绪');
  createWindow(); // 自定义创建窗口的函数
});

// 所有窗口关闭时触发(Windows/Linux下退出应用)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') { // 排除macOS(macOS窗口关闭后应用仍驻留)
    app.quit();
  }
});

// macOS下点击 Dock 图标时激活应用
app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow(); // 重新创建窗口
  }
});
2. 创建与管理窗口(渲染进程载体)

通过BrowserWindow创建窗口,每个窗口对应一个独立的渲染进程,主进程控制窗口的大小、位置、显示/隐藏等。

实例

javascript 复制代码
// main.js(主进程)
const { BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
  // 创建主窗口(渲染进程的载体)
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'), // 预加载脚本(进程通信桥梁)
      contextIsolation: true // 强制开启上下文隔离(安全要求)
    }
  });

  // 加载渲染进程页面(HTML文件)
  mainWindow.loadFile('index.html');

  // 控制窗口行为(如最大化、最小化)
  mainWindow.maximize(); // 窗口最大化
}
3. 访问系统资源(渲染进程无权直接访问)

主进程运行在Node.js环境,可直接访问文件系统、环境变量、系统命令等敏感资源,渲染进程需通过主进程间接访问。

实例:主进程读取环境变量并处理文件:

javascript 复制代码
// main.js(主进程)
const fs = require('fs');
const path = require('path');

// 读取系统环境变量(渲染进程无法直接访问process.env)
const apiBaseUrl = process.env.API_BASE_URL || 'https://default-api.com';

// 写入文件(渲染进程无权直接调用fs模块)
function writeToFile(content) {
  fs.writeFileSync(path.join(__dirname, 'data.txt'), content);
}
4. 作为进程间通信(IPC)的中介

主进程通过ipcMain监听渲染进程的请求,处理后返回结果;也可主动通过webContents.send向渲染进程发送消息。

实例:主进程处理渲染进程的"获取环境变量"请求:

javascript 复制代码
// main.js(主进程)
const { ipcMain } = require('electron');

// 监听渲染进程的"get-env-vars"请求
ipcMain.handle('get-env-vars', () => {
  // 筛选需要暴露给渲染进程的环境变量(避免敏感信息泄露)
  return {
    apiUrl: process.env.API_URL,
    appMode: process.env.APP_MODE || 'development'
  };
});
5. 管理菜单、托盘、对话框等系统级UI

主进程负责创建应用菜单、系统托盘图标、文件选择对话框等,这些是系统级交互,无法在渲染进程中直接实现。

实例:创建应用菜单:

javascript 复制代码
// main.js(主进程)
const { Menu } = require('electron');

const menuTemplate = [
  {
    label: '文件',
    submenu: [
      { label: '打开', click: () => console.log('打开文件') },
      { label: '保存', click: () => console.log('保存文件') }
    ]
  }
];

const menu = Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(menu); // 设置应用菜单

二、渲染进程如何从环境变量获取API参数配置?

渲染进程运行在Chromium环境中,默认无法直接访问process.env (出于安全隔离,contextIsolation: true时完全隔离Node API)。因此,需通过以下流程获取环境变量:

  1. 主进程读取环境变量 (主进程有权访问process.env);
  2. 通过IPC通信将环境变量传递给渲染进程(主进程作为中介);
  3. 渲染进程调用预加载脚本暴露的接口获取变量。
详细步骤与实例:
1. 主进程准备环境变量并监听IPC请求
javascript 复制代码
// main.js(主进程)
const { ipcMain } = require('electron');

// 1. 主进程读取环境变量(可从系统环境变量或配置文件获取)
const envConfig = {
  apiBaseUrl: process.env.API_BASE_URL || 'https://api.example.com',
  timeout: process.env.API_TIMEOUT || 5000,
  // 敏感信息(如API密钥)不应暴露给渲染进程,主进程自行处理
  // secretKey: process.env.SECRET_KEY // 仅主进程内部使用
};

// 2. 监听渲染进程的"get-env-config"请求,返回非敏感配置
ipcMain.handle('get-env-config', () => {
  return envConfig; // 只返回渲染进程需要的非敏感配置
});
2. 预加载脚本(preload.js)暴露IPC接口

预加载脚本是唯一能在渲染进程中安全暴露主进程API的地方(运行在独立上下文,兼具Node和浏览器环境权限)。

javascript 复制代码
// preload.js
const { contextBridge, ipcRenderer } = require('electron');

// 向渲染进程的全局对象(window)暴露安全接口
contextBridge.exposeInMainWorld('electronEnv', {
  // 封装获取环境配置的方法(调用主进程的IPC接口)
  getConfig: () => ipcRenderer.invoke('get-env-config')
});
3. 渲染进程调用接口获取环境变量

渲染进程通过预加载脚本暴露的window.electronEnv获取配置。

html 复制代码
<!-- index.html(渲染进程页面) -->
<!DOCTYPE html>
<html>
  <body>
    <div id="config"></div>
    <script src="renderer.js"></script>
  </body>
</html>
javascript 复制代码
// renderer.js(渲染进程脚本)
// 调用预加载脚本暴露的接口获取环境配置
window.electronEnv.getConfig().then(config => {
  console.log('从主进程获取的环境配置:', config);
  // 输出:{ apiBaseUrl: "https://api.example.com", timeout: 5000 }
  
  // 在页面中显示配置
  document.getElementById('config').textContent = 
    `API地址:${config.apiBaseUrl},超时时间:${config.timeout}ms`;
});
4. 如何设置环境变量?

可通过启动命令传入环境变量(推荐使用cross-env跨平台设置):

bash 复制代码
# 安装cross-env(跨平台设置环境变量的工具)
npm install cross-env --save-dev

package.json中配置启动脚本:

json 复制代码
{
  "scripts": {
    "start": "cross-env API_BASE_URL=https://dev-api.example.com electron .",
    "start:prod": "cross-env API_BASE_URL=https://prod-api.example.com electron ."
  }
}

运行时,主进程的process.env.API_BASE_URL会被设置为对应的值。

三、关键注意事项

  1. 敏感信息不得暴露给渲染进程

    如API密钥、数据库密码等,必须由主进程保管并直接处理相关逻辑(如发起带密钥的请求),避免通过IPC传递给渲染进程。

  2. 环境变量需过滤后传递

    主进程应仅将渲染进程必需的非敏感配置(如API地址、超时时间)传递给渲染进程,避免暴露系统级环境变量(如PATHHOME)。

  3. 禁用nodeIntegration: true

    开启nodeIntegration会让渲染进程直接访问Node API(包括process.env),存在极大安全风险(如XSS攻击可能读取系统文件),必须保持默认的nodeIntegration: false

  4. 依赖预加载脚本通信

    渲染进程与主进程的所有通信必须通过预加载脚本的contextBridge暴露,禁止直接在渲染进程中引入electron模块。

总结

  • 主进程是系统资源管理者和进程中介,负责窗口管理、环境变量读取、安全逻辑处理等核心功能;
  • 渲染进程 需通过IPC向主进程请求环境变量,不可直接访问process.env
  • 通信必须通过预加载脚本的contextBridge实现,确保安全隔离。

这种设计既保证了应用的安全性,又明确了进程职责划分,是Electron开发的最佳实践。