课堂笔记
2024年12月23日...大约 4 分钟
课堂笔记
- 生命周期
- 渲染进程的权限
- 预加载脚本
- 上下文隔离
生命周期
我们在最早就接触了一个 Electron 的生命周期方法:
// whenReady 是一个生命周期方法,当 Electron 完成初始化后会调用这个方法
app.whenReady().then(() => {
createWindow();
});
该方法是在 Electron 完成初始化后会调用这个方法。
- will-finish-launching:在应用完成基本启动进程之后触发
- ready:当 Electron 完成初始化后触发
- window-all-closed:所有窗口都关闭的时候触发,特别是在 windows 和 linux 里面,所有窗口都关闭则意味着应用退出
app.on("window-all-closed", () => {
// 当操作系统不是 darwin(macOS) 的时候
if (process.platform !== "darwin") {
// 退出应用
app.quit();
}
});
- before-quit:退出应用之前触发
- will-quit:即将退出应用的时候
- quit:退出应用的时候
你可以在 https://www.electronjs.org/docs/latest/api/app 看到更多的 app 模块的生命周期方法。
除了 app 模块以外,BrowserWindow 也有很多的事件钩子:
- closed:当窗口被关闭的时候
- focus:当窗口聚焦的时候
- show:当窗口展示的时候
- hide:当窗口隐藏的时候
- maxmize:当窗口最大化的时候
- minimize:当窗口最小化的时候
你可以在 https://www.electronjs.org/docs/latest/api/browser-window 这里看到更多的关于 BrowserWindow 的事件钩子。
一个简单的使用示例:
win.on("minimize", () => {
console.log("窗口最小化了");
});
渲染进程的权限
在 Electron 中,出于安全性的考虑,实际上提供给渲染进程的可用的 API 是比较少的。

在早期的时候,Electron 团队其实提供了一个名为 remote 的模块,该模块也能够达到主进程和渲染进程互访的目的,降低两者之间通信的难度。
但是该模块本身带来了一些问题:
- 性能问题
- 通过 remote 模块倒是可以使用原本只能在主进程里面使用的对象、类型、方法,但是这些操作都是跨进程的。在操作系统中,一旦涉及到跨进程的操作,性能上的损耗可能会达到几百倍甚至上千倍。
- 假设我们在渲染进程里面通过 remote 模块使用了主进程的 BrowserWindow 来创建一个窗口实例,不仅创建该窗口实例的过程很慢,你后面使用这个窗口实例的过程也很慢,小到更新属性,大到使用方法,都是跨进程。
- 影子对象
- 在渲染进程中通过 remote 模块使用到了主进程里面的某个对象,看上去是得到了主进程里面真正的对象,但实际上不是,得到的是一个对象的代理(影子)。
- 这个影子对象和主进程里面真正的原本的对象还是有一定区别。首先,原本的对象的原型链上面的属性是不会被映射到渲染进程的影子对象上面。另外,类似于 NaN、Infinity 这样的值在渲染进程的影子对象里面得到是 undefined。这意味着假设在主进程里面有一个方法返回一个 NaN 的值,通过渲染进程的影子对象来调用该方法的话,得到的却是 undefined。
- 存在安全性问题
- 使用 remote 模块后,渲染进程可以很轻松的直接访问主进程的模块和对象,这会带来一些安全性问题,可能会导致一些渲染进程里面的恶性代码利用该特性进行攻击。
Electron 团队意识到这个问题之后,将 remote 模块标记为了“不赞成”。
从 Electron 10 版本开始,要使用 remote 模块,必须手动开启
const { app, BrowserWindow } = require("electron");
// 创建窗口方法
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
enableRemoteModule: true, // 允许使用 remote 模块
},
});
win.loadFile("window/index.html");
};
// whenReady 是一个生命周期方法,当 Electron 完成初始化后会调用这个方法
app.whenReady().then(() => {
createWindow();
});
开启之后,就可以在渲染进程中直接通过 remote 使用一些原本只能在主进程中才能使用的 API
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button id="btn">新建页面</button>
<script>
let { remote } = require("electron");
let newWin = null;
btn.onclick = function () {
// 创建新的渲染进程
newWin = new remote.BrowserWindow({
webPreferences: { nodeIntegration: true },
});
// 在新的渲染进程中加载 html 文件
newWin.loadFile("./index2.html");
};
</script>
</body>
</html>
之后,从 Electron14版本开始,彻底废除了 remote 模块。
不过,如果你坚持要用,也有一个替代品,就是 @electron/remote:https://www.npmjs.com/package/@electron/remote
Powered by Waline v3.3.2