|
## 一、基本作用
在Electron中,`nodeIntegration: true`的作用主要是允许渲染进程(即BrowserWindow实例所代表的进程)访问Node.js的API和环境。以下是对其作用的具体解释:
**启用Node.js集成**:当nodeIntegration设置为true时,渲染进程将能够使用Node.js的模块和API。
这意味着在渲染进程的JavaScript代码中,你可以通过`require`函数导入Node.js模块,并使用这些模块提供的功能。
---
## 二、应用场景
**增强渲染进程的能力**:通过访问Node.js的API,渲染进程可以执行文件系统操作、网络通信等底层任务,从而增强应用的功能。
**实现前后端交互**:在Electron应用中,主进程通常负责处理底层逻辑和与操作系统的交互,而渲染进程负责呈现用户界面。
通过启用nodeIntegration,渲染进程可以直接与Node.js后端进行通信,实现前后端的无缝交互。
---
## 三、注意事项
**安全性**:启用nodeIntegration可能会带来安全风险,因为渲染进程将能够执行任意Node.js代码。
因此,在开发Electron应用时,需要谨慎考虑是否需要启用此选项,
并采取必要的安全措施来保护应用免受恶意代码的攻击。
**Electron版本差异**:在Electron 5.0.0及更高版本中,nodeIntegration默认被禁用。
因此,如果你需要启用它,需要在BrowserWindow的webPreferences中明确设置`nodeIntegration: true`。
**contextIsolation**:在启用nodeIntegration时,建议同时启用contextIsolation(设置为true)。
这可以将渲染进程的JavaScript上下文与Node.js环境隔离,从而降低安全风险。
然而,需要注意的是,启用contextIsolation后,将无法使用remote模块直接在渲染进程中调用主进程的方法。
此时,需要通过其他方式(如IPC通信)来实现前后端的交互。
**综上所述**,`nodeIntegration: true`在Electron中的作用是允许渲染进程访问Node.js的API和环境,从而增强应用的功能。
然而,在启用此选项时,需要谨慎考虑安全性问题,并采取必要的措施来保护应用的安全。
|
|
|
|
|
|
|
|
|
|
## process.platform
`process.platform` 属性返回一个字符串,标识编译 Node.js 二进制文件的操作系统平台。
### 可能的值
Currently possible values are:
'aix'
'darwin'
'freebsd'
'linux'
'openbsd'
'sunos'
'win32'
### 示例代码
```javascript
const { platform } = require('node:process');
console.log(`This platform is ${platform}`);
```
### 参考文档
https://nodejs.org/api/process.html#process_process_platform
|
|
## Electron 进程模型说明总结
Electron 继承了 Chromium 的多进程架构,主要由主进程、渲染进程和工具进程组成。以下是各进程的核心功能总结:
### 一、进程类型对比
| 进程类型 | 运行环境 | 核心功能 | 关键特性 |
|---------|---------|---------|---------|
| **主进程** | Node.js | 应用入口点、窗口管理、生命周期控制、原生API调用 | 每个应用只有一个;可创建和管理BrowserWindow;控制应用生命周期(app模块);提供原生桌面功能(菜单、对话框等) |
| **渲染进程** | 浏览器环境 | 负责页面渲染和UI交互 | 每个窗口独立进程;遵循Web标准;不能直接访问Node.js API;可使用HTML/CSS/JavaScript构建界面 |
| **预加载脚本** | 混合环境 | 在渲染进程加载前执行,桥接主进程和渲染进程 | 可访问Node.js API;与渲染进程共享window全局;使用contextBridge安全暴露API |
| **工具进程** | Node.js | 处理不可信服务、CPU密集型任务、易崩溃组件 | 通过UtilityProcess API创建;支持与渲染进程通过MessagePort通信 |
### 二、进程间通信与交互
**主进程 ↔ 渲染进程**
- 通过 `ipcRenderer` 和 `ipcMain` 模块进行进程间通信
- 预加载脚本通过 `contextBridge.exposeInMainWorld` 安全暴露API
**预加载脚本示例**
```javascript
// preload.js
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
desktop: true
})
// renderer.js
console.log(window.myAPI) // => { desktop: true }
```
### 三、TypeScript类型支持
| 路径别名 | 包含类型 |
|---------|---------|
| `electron/main` | 主进程模块类型定义 |
| `electron/renderer` | 渲染进程模块类型定义 |
| `electron/common` | 跨进程通用模块类型定义 |
### 四、设计优势
多进程架构的主要优势在于**隔离性**——单个渲染进程崩溃不会影响整个应用,这与现代浏览器的设计理念一致,既提升了稳定性也增强了安全性。
|
|
## process.env 简介
`process.env` 是 Node.js 中的一个全局对象,包含了当前进程的环境变量。在 Electron 应用中,我们可以通过它来读取和设置环境变量,实现配置管理和跨平台兼容。
---
## 一、基本概念
### 什么是环境变量?
环境变量是操作系统存储的键值对,用于配置系统和应用程序的行为。例如:
- `PATH`:系统可执行文件搜索路径
- `NODE_ENV`:Node.js 运行环境(development/production)
- `USER`:当前用户名
### process.env 的作用
| 功能 | 说明 |
|------|------|
| **读取配置** | 从 `.env` 文件或系统环境变量中读取应用配置 |
| **环境判断** | 区分开发/生产环境,执行不同逻辑 |
| **路径管理** | 获取用户目录、系统目录等信息 |
| **跨平台兼容** | 根据不同平台设置不同的配置 |
---
## 二、D:\wks\elec 项目中的使用
### 1. .env 文件配置
在 `D:\wks\elec\.env` 中定义环境变量:
```env
# Vite 开发服务器配置
VITE_PORT=5273
VITE_HOST=0.0.0.0
# Electron 配置
ELECTRON_DEV_URL=http://localhost:5273
# API 配置
VITE_API_BASE=http://127.0.0.1:8888/api/v1
# 应用配置
NODE_ENV=development
```
### 2. main.js 中读取环境变量
```javascript
// 加载 .env 文件
require('dotenv').config();
// 读取环境变量(带默认值)
const ELECTRON_DEV_URL = process.env.ELECTRON_DEV_URL || 'http://localhost:5173';
const NODE_ENV = process.env.NODE_ENV || 'development';
// Windows 平台特殊处理
if (process.platform === 'win32') {
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
}
```
### 3. 常用 process.env 属性
| 属性 | 说明 | 示例值 |
|------|------|--------|
| `NODE_ENV` | 运行环境 | `'development'` / `'production'` |
| `ELECTRON_DEV_URL` | 开发服务器地址 | `'http://localhost:5273'` |
| `VITE_PORT` | Vite 端口 | `'5273'` |
| `VITE_API_BASE` | API 基础路径 | `'http://127.0.0.1:8888/api/v1'` |
---
## 三、实际应用场景
### 场景 1:环境判断
```javascript
const isDev = process.env.NODE_ENV === 'development' ||
process.env.NODE_ENV === undefined ||
!app.isPackaged;
if (isDev) {
// 开发环境:加载本地 Vite 服务器
mainWindow.loadURL(ELECTRON_DEV_URL);
mainWindow.webContents.openDevTools();
} else {
// 生产环境:加载打包后的文件
mainWindow.loadFile(path.join(__dirname, 'dist/index.html'));
}
```
### 场景 2:跨平台配置
```javascript
// Windows 平台特殊处理
if (process.platform === 'win32') {
console.log('[Platform] Windows detected');
console.log('[Encoding] UTF-8 mode enabled');
// Windows GPU 配置
app.commandLine.appendSwitch('enable-gpu-rasterization');
app.commandLine.appendSwitch('disable-software-rasterizer');
} else if (process.platform === 'darwin') {
// macOS 特定配置
app.commandLine.appendSwitch('enable-gpu-rasterization');
}
```
### 场景 3:动态配置加载
```javascript
// 从环境变量读取 API 地址
const API_BASE = process.env.VITE_API_BASE || 'http://localhost:8888/api/v1';
// 在渲染进程中使用(通过 preload 脚本暴露)
contextBridge.exposeInMainWorld('config', {
apiBase: API_BASE,
isDev: process.env.NODE_ENV === 'development'
});
```
---
## 四、环境变量优先级
在 `D:\wks\elec` 项目中,环境变量的加载优先级:
1. **系统环境变量**(最高优先级)
2. **.env 文件**(通过 dotenv 加载)
3. **代码中的默认值**(作为后备)
```javascript
// 优先级示例
const config = {
apiUrl: process.env.API_URL || // 1. 系统环境变量
process.env.VITE_API_BASE || // 2. .env 文件
'http://localhost:8888/api/v1' // 3. 默认值
};
```
---
## 五、注意事项
| 注意事项 | 说明 |
|---------|------|
| **安全性** | 不要在 `.env` 文件中存储敏感信息(如密码、密钥) |
| **版本控制** | 将 `.env` 添加到 `.gitignore`,提供 `.env.example` 作为模板 |
| **类型转换** | `process.env` 的值都是字符串,需要手动转换为数字或布尔值 |
| **打包部署** | 生产环境中需要在启动前设置环境变量 |
**类型转换示例**:
```javascript
// 错误:process.env 的值都是字符串
const port = process.env.VITE_PORT; // "5273" (字符串)
const useSSL = process.env.USE_SSL; // "false" (字符串,不是布尔值)
// 正确:手动转换
const port = parseInt(process.env.VITE_PORT) || 5273;
const useSSL = process.env.USE_SSL === 'true';
```
---
## 六、参考文档
- [Node.js process.env 文档](https://nodejs.org/api/process.html#process_process_env)
- [dotenv 包文档](https://www.npmjs.com/package/dotenv)
- [Electron 环境变量最佳实践](https://www.electronjs.org/docs/latest/tutorial/faq#how-can-i-get-the-version-of-electron-and-versions-of-other-dependencies)
|
|
|
|
|
|
## 调试相关资源
### DevTools扩展
https://www.electronjs.org/zh/docs/latest/tutorial/devtools-extension
### 调试应用
https://www.electronjs.org/zh/docs/latest/tutorial/application-debugging
|
|
|
|
|
|
|
|
## 渲染器进程
每个 Electron 应用都会为每个打开的 BrowserWindow ( 与每个网页嵌入 ) 生成一个单独的渲染器进程。
洽如其名,渲染器负责 **渲染** 网页内容。
## Preload 脚本
预加载(preload)脚本包含了那些执行于渲染器进程中,
且先于网页内容开始加载的代码。
这些脚本虽运行于渲染器的环境中,却能访问 Node.js API 而拥有了更多的权限。
预加载脚本可以在 BrowserWindow 构造方法中的 webPreferences 选项里被附加到主进程。
### 配置 preload 脚本
```javascript
const { BrowserWindow } = require('electron')
// ...
const win = new BrowserWindow({
webPreferences: {
preload: 'path/to/preload.js'
}
})
// ...
```
## Context Isolation(上下文隔离)
因为预加载脚本与浏览器共享同一个全局 Window 接口,并且可以访问 Node.js API,
所以它通过在全局 window 中暴露任意 API 来增强渲染器,以便你的网页内容使用。
Although preload scripts share a window global with the renderer they're attached to,
you cannot directly attach any variables from the preload script to window
because of the `contextIsolation` default.
**语境隔离(Context Isolation)**意味着 预加载脚本与渲染器的主要运行环境 是隔离开来的,
以避免泄漏任何具特权的 API 到您的网页内容代码中。
Instead, use the `contextBridge` module to accomplish this securely:
### preload.js
```javascript
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
ping: () => ipcRenderer.invoke('ping'),
globalVisitCount: true
// 除函数之外,我们也可以暴露变量
})
```
### renderer.js
```javascript
console.log(window.versions.globalVisitCount) // => { desktop: true }
console.log(versions.globalVisitCount) // => { desktop: true }
```
**说明**:`contextBridge.exposeInMainWorld`可以通过全局变量`window`打通
预加载脚本与渲染进程的脚本之间的隔离。
|
|
|
|
|
|
|
|
|