Electron 核心概念
app、BrowserWindow、webContents、进程模型、上下文隔离。
四个核心对象
| Object | Represents | Typical use |
|---|---|---|
app | 整个应用 | 生命周期、单实例、开机自启 |
BrowserWindow | 一个原生窗口 | 尺寸、标题、菜单、显示隐藏 |
webContents | 窗口里的页面 | 加载 URL、执行 JS、发消息 |
session | 一个分区的存储与网络配置 | Cookie、缓存、代理、权限 |
app 的常用能力
const { app } = require('electron');
app.whenReady().then(() => { /* 可以创建窗口了 */ });
app.getVersion(); // package.json 里的 version
app.getName();
app.getPath('userData'); // 用户数据目录(存配置、数据库)
app.getPath('downloads');
app.setLoginItemSettings({ openAtLogin: true }); // 开机自启
app.quit(); // 退出
app.exit(0); // 立即退出,不触发 before-quit
// 单实例:第二次启动时激活已有窗口
const gotLock = app.requestSingleInstanceLock();
if (!gotLock) {
app.quit();
} else {
app.on('second-instance', () => {
const win = BrowserWindow.getAllWindows()[0];
if (win) { if (win.isMinimized()) win.restore(); win.focus(); }
});
}userData is where config belongs: %APPDATA% on Windows, ~/Library/Application Support on macOS, ~/.config on Linux. Never write into the install directory — it may not be writable.
BrowserWindow 的常用方法
const win = new BrowserWindow({
width: 1200, height: 800,
minWidth: 800, minHeight: 600,
frame: true, // false = 无边框,自己做标题栏
show: false, // 先隐藏,ready-to-show 再显示,避免白屏闪烁
backgroundColor: '#0f172a',
webPreferences: { preload, contextIsolation: true, nodeIntegration: false }
});
win.once('ready-to-show', () => win.show());
win.loadFile('index.html');
win.setTitle('我的应用');
win.maximize();
win.setAlwaysOnTop(true);
win.hide();
win.webContents.send('ping', 'hello'); // 给页面发消息show: false plus ready-to-show is the standard fix for the white flash on startup: by default the window appears blank before content renders, which looks broken.
进程模型
Main process
├── Renderer process (窗口 1)
├── Renderer process (窗口 2)
├── GPU process
└── Utility processes (网络、音频等)One renderer per window: a crashed window leaves the others and the main process intact — the isolation Chromium's multi-process design provides. If the main process crashes, the whole app dies.
上下文隔离
// 默认且推荐:隔离
new BrowserWindow({
webPreferences: { contextIsolation: true, nodeIntegration: false }
});contextIsolation: true puts the preload script and the page in separate JS contexts, so the page monkey-patching Object.prototype cannot affect the bridge. Turning it off removes the wall and hands Node to the page.
nodeIntegration: true, a pre-2018 pattern. Today that lets any XSS in the page read arbitrary files and run arbitrary commands — a security audit will fail it outright.四个核心对象
| 对象 | 代表 | 典型用法 |
|---|---|---|
| app | 整个应用 | 生命周期、单实例、开机自启 |
| 窗口 | 一个原生窗口 | 尺寸、标题、菜单、显示隐藏 |
| 网页内容 | 窗口里的页面 | 加载 URL、执行 JS、发消息 |
| 会话 | 一个分区的存储与网络配置 | Cookie、缓存、代理、权限 |
app 的常用能力
const { app } = require('electron');
app.whenReady().then(() => { /* 可以创建窗口了 */ });
app.getVersion(); // package.json 里的 version
app.getName();
app.getPath('userData'); // 用户数据目录(存配置、数据库)
app.getPath('downloads');
app.setLoginItemSettings({ openAtLogin: true }); // 开机自启
app.quit(); // 退出
app.exit(0); // 立即退出,不触发 before-quit
// 单实例:第二次启动时激活已有窗口
const gotLock = app.requestSingleInstanceLock();
if (!gotLock) {
app.quit();
} else {
app.on('second-instance', () => {
const win = BrowserWindow.getAllWindows()[0];
if (win) { if (win.isMinimized()) win.restore(); win.focus(); }
});
}userData 是存配置的正确位置:Windows 在 %APPDATA%,macOS 在 ~/Library/Application Support,Linux 在 ~/.config。不要往安装目录写——那里可能没有写权限。
BrowserWindow 的常用方法
const win = new BrowserWindow({
width: 1200, height: 800,
minWidth: 800, minHeight: 600,
frame: true, // false = 无边框,自己做标题栏
show: false, // 先隐藏,ready-to-show 再显示,避免白屏闪烁
backgroundColor: '#0f172a',
webPreferences: { preload, contextIsolation: true, nodeIntegration: false }
});
win.once('ready-to-show', () => win.show());
win.loadFile('index.html');
win.setTitle('我的应用');
win.maximize();
win.setAlwaysOnTop(true);
win.hide();
win.webContents.send('ping', 'hello'); // 给页面发消息show: false + ready-to-show 是消除启动白屏的标准做法。默认窗口会先显示空白再渲染内容,用户看到一闪的白块,观感很差。
进程模型
Main process
├── Renderer process (窗口 1)
├── Renderer process (窗口 2)
├── GPU process
└── Utility processes (网络、音频等)一个窗口一个渲染进程。窗口崩了不影响其他窗口,也不影响主进程——这是 Chromium 的多进程架构带来的隔离。主进程崩了整个应用就没了。
上下文隔离
// 默认且推荐:隔离
new BrowserWindow({
webPreferences: { contextIsolation: true, nodeIntegration: false }
});contextIsolation: true 让预加载脚本和页面跑在不同的 JS 上下文里,页面改 Object.prototype 也影响不到预加载。关掉它等于把桥拆了,页面能直接摸到 Node。
nodeIntegration: true,那是 2018 年之前的写法。现在这么做等于让页面里的任何 XSS 都能读任意文件、执行任意命令——安全审计会直接判不通过。