Electron
中,主进程和渲染进程是被换分成不同的功能的,主进程有完整的Node
环境,而渲染进程默认是运行的是浏览器环境。这样划分的好处是:
安全性:渲染进程运行在沙盒环境中,限制了对底层操作系统的访问和敏感资源的操作。直接在渲染进程中开启 Node.js 环境可能会带来潜在的安全风险,因为 Node.js 具有强大的功能和系统级访问权限,可能会被恶意利用或不当使用。
性能:渲染进程主要负责显示用户界面,处理用户交互和渲染页面。将 Node.js 环境直接放在渲染进程中可能会对性能产生负面影响,因为 Node.js 的运行环境相对较重,可能会消耗大量的内存和 CPU 资源,从而影响渲染进程的响应性能和用户体验。
分离关注点:主进程和渲染进程在 Electron 中有不同的职责和关注点。主进程负责管理应用程序的生命周期、系统级功能和与底层操作系统的交互,而渲染进程负责处理用户界面和与用户的交互。通过进程间通信,可以保持这种分离,使代码更易于维护、调试和扩展。
但是我们知道,开发的时候,我们很可能需要在渲染进程中进行一些只能在主进程中运行的操作。这就需要进程间通信了,在渲染进程中需要的时候,可以给主进程发信息,让主进程帮忙处理。
我们之前说过一种直接给渲染进程开启
node
环境,使用remote
模块的方式,并不十分推荐。
预加载脚本(preload
)
Electron
不推荐在渲染进程开启Nodejs
环境,那也就意味着我们无法在渲染进程中使用NodeJS
API,但有时候我们又真的很需要使用NodeJS
API。“Preload 脚本”就是用来解决这个问题的。
用大白话来说就是:我们可以在主进程创建窗口的时候,指定一些脚本(内容是我们定的),这些脚本将来是在渲染进程中使用的,但是先于网页内容加载,由于是在主进程的时候就预加载了,所以能使用NodeJS
API。
从 Electron 20 开始,预加载脚本默认 沙盒化 ,不再拥有完整 Node.js 环境的访问权,实际上,这意味着我们只拥有一个 require
函数,这个函数只能访问一组有限的 API。
可用的 API | 详细信息 |
---|---|
Electron 模块 | 仅限渲染进程模块 |
Node.js 模块 | 、、 |
Polyfilled 的全局模块 | 、、、 |
目前我使用的electron
的版本是 v25
。下面写个示例体验一下:
创建一个预加载脚本
p1.js
,我们可以在里面编写我们的代码,此脚本中可以使用Nodejs
API。// p1.js const { contextBridge } = require('electron') // 将xxxx对象暴露给渲染进程中的全局对象,以便在渲染进程中直接访问 contextBridge.exposeInMainWorld('xxxx', { name: '如花', run: function () { return '小子你跑的真快' } })
contextBridge.exposeInMainWorld(apiKey, apiObject)
此方法将指定的
apiObject
对象暴露给渲染进程中的全局对象,以便在渲染进程中直接访问。apiKey
是一个字符串,用于在全局对象中创建一个属性,该属性将指向apiObject
。创建窗口的时候,指定
preload
配置// main.js
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
// 配置预加载脚本(这里需要是个绝对路径)
preload: path.join(__dirname, 'p1.js')
},
})
win.loadFile('index.html')在渲染进程中使用预加载脚本暴露的方法
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>您好,世界</title>
</head>
<body>
<h1>您好,世界!</h1>
<script>
// 调用预处理脚本中暴露的数据
console.log(xxxx.name);
console.log(xxxx.run());
</script>
</body>
</html>
参考文档:https://www.electronjs.org/zh/docs/latest/tutorial/tutorial-preload